File: /home/wbwebdes/domains/survey.nailsbyrianne.nl/public_html/tmp/assets/9e187765/build/embeddables.js
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var embedo = createCommonjsModule(function (module) {
(function (root, factory) {
if (module.exports) {
module.exports = factory();
} else if (root) {
root.Embedo = window.Embedo = factory();
}
})(commonjsGlobal, function () {
/**
* @class Embedo Prototype
*
* @param {object} options Initialize options.
*/
function Embedo(options) {
this.options = options || Embedo.defaults.OPTIONS;
this.requests = [];
this.events = [];
this.init(this.options);
return this;
}
/**
* @constant
* Embedo defaults
*
* @description Embedo defaults contains basic configuration and values required to build internal engine.
*/
Object.defineProperty(Embedo, 'defaults', {
value: {
OPTIONS: {
facebook: null,
twitter: false,
instagram: false,
pinterest: false
},
SOURCES: {
facebook: {
GLOBAL: 'FB',
SDK: '//connect.facebook.net/${locale}/sdk.js',
oEmbed: '//graph.facebook.com/${version}/oembed_${type}',
REGEX: /(?:(?:http|https):\/\/)?(?:www.)?facebook.com\/(?:(?:\w)*#!\/)?(?:pages\/)?([\w\-]*)?/g,
PARAMS: {
version: 'v3.2',
cookie: true,
appId: null,
access_token: null
}
},
twitter: {
GLOBAL: 'twttr',
SDK: '//platform.twitter.com/widgets.js',
oEmbed: '//publish.twitter.com/oembed',
REGEX: /^http[s]*:\/\/[www.]*twitter(\.[a-z]+).*/i,
PARAMS: {}
},
instagram: {
GLOBAL: 'instgrm',
SDK: '//www.instagram.com/embed.js',
oEmbed: '//graph.facebook.com/${version}/instagram_oembed',
REGEX: /(http|https)?:\/\/(www\.)?instagram.com\/p\/[a-zA-Z0-9_\/\?\-\=]+/gi,
PARAMS: {
version: 'v8.0',
access_token: null
}
},
youtube: {
GLOBAL: null,
SDK: null,
oEmbed: '//www.youtube.com/embed/',
REGEX: /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:m\.)?(?:youtu(?:be)?\.com\/(?:v\/|embed\/|watch(?:\/|\?v=))|youtu\.be\/)((?:\w|-){11})(?:\S+)?$/,
PARAMS: null
},
pinterest: {
GLOBAL: 'PinUtils',
SDK: '//assets.pinterest.com/js/pinit.js',
oEmbed: null,
REGEX: /(https?:\/\/(ww.)?)?pinterest(\.[a-z]+).*/i,
PARAMS: {}
},
vimeo: {
GLOBAL: null,
SDK: null,
oEmbed: '//vimeo.com/api/oembed.json',
REGEX: /(http|https)?:\/\/(www\.)?vimeo(\.[a-z]+)\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|)(\d+)(?:|\/\?)/,
PARAMS: {}
},
github: {
GLOBAL: null,
SDK: null,
oEmbed: null,
REGEX: /(http|https):\/\/gist\.github\.com\/(\w+)\/(\w+)/,
PARAMS: {}
},
soundcloud: {
GLOBAL: null,
SDK: null,
oEmbed: '//soundcloud.com/oembed',
REGEX: /^(http|https):\/\/soundcloud\.com\/(\w+)\/.*$/,
PARAMS: {}
}
},
RESTRICTED: ['url', 'strict', 'height', 'width', 'centerize', 'jsonp']
},
writable: false,
enumerable: true,
configurable: false
});
// Application Logger
Object.defineProperty(Embedo, 'log', {
value: function log(type) {
if (!Embedo.debug) {
return;
}
if (typeof console !== 'undefined' && typeof console[type] !== 'undefined') {
console[type].apply(console, Array.prototype.slice.call(arguments, 1));
}
},
writable: false,
enumerable: true,
configurable: false
});
// Plugins Loader
Object.defineProperty(Embedo, 'plugins', {
value: function load(plugins) {
if (!plugins) {
return;
}
if (plugins instanceof Array) {
plugins.forEach(function (plugin) {
if (typeof plugin === 'function') {
plugin(Embedo);
}
});
} else if (plugins === 'fuction') {
plugins(Embedo);
}
},
writable: false,
enumerable: true,
configurable: false
});
/**
* Helper utlities
* @method utils
*
* @private
*/
Object.defineProperty(Embedo, 'utils', {
value: Object.create({
/**
* @function uuid
*/
uuid: function uuid() {
var primary = (Math.random() * 0x10000) | 0;
var secondary = (Math.random() * 0x10000) | 0;
primary = ('000' + primary.toString(36)).slice(-3);
secondary = ('000' + secondary.toString(36)).slice(-3);
return 'embedo_' + primary + secondary;
},
/**
* @function extend
* @returns {object}
*/
extend: function extend(obj) {
obj = obj || {};
for (var i = 1; i < arguments.length; i++) {
if (!arguments[i]) {
continue;
}
for (var key in arguments[i]) {
if (arguments[i].hasOwnProperty(key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
},
/**
* @function merge
*
* @param {object} destination
* @param {object} source
* @param {array} preserve
* @returns
*/
merge: function merge(destination, source, preserve) {
preserve = preserve || [];
for (var property in source) {
if (preserve.indexOf(property) === -1) {
destination[property] = source[property];
}
}
return destination;
},
/**
* @func sequencer
* Breaks down array into sequencer
*
* @param {Array} array
* @param {Number} size
* @returns
*/
sequencer: function sequencer() {
var args = arguments;
return {
then: function (done) {
var counter = 0;
for (var i = 0; i < args.length; i++) {
args[i](callme);
}
function callme() {
counter++;
if (counter === args.length) {
done();
}
}
}
};
},
/**
* @func replacer
* Replaces ${entity} with object key/value pair
*
* @param {string} str
* @param {object} obj
*/
replacer: function replacer(str, obj) {
if (!str || !obj) {
return;
}
if (obj) {
for (var key in obj) {
if (str) {
str = str.split('${' + key + '}').join(obj[key]);
}
}
}
return str;
},
/**
* @func observer
*
* Deferred Implementation for Object
*/
observer: (function () {
function Deferred() {
this.resolved = [];
this.rejected = [];
}
Deferred.prototype = {
execute: function (list, args) {
var i = list.length;
args = Array.prototype.slice.call(args);
while (i--) {
list[i].apply(null, args);
}
},
resolve: function () {
this.execute(this.resolved, arguments);
},
reject: function () {
this.execute(this.rejected, arguments);
},
done: function (callback) {
this.resolved.push(callback);
return this;
},
fail: function (callback) {
this.rejected.push(callback);
return this;
}
};
return Deferred;
})(),
camelToSnake: function camelToSnake(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
},
/**
* @function validateURL
*
* @param {string} url
* @returns
*/
validateURL: function validateURL(url) {
return /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url);
},
/**
* @function generateElement
* Generates DOM element
*
* @param {string} source
* @param {object} attributes
* @param {string} html
* @returns HTMLElement
*/
generateElement: function generateElement(type, attributes, html) {
var el = document.createElement(type);
Object.keys(attributes || {}).forEach(function (type) {
el.setAttribute(type, attributes[type]);
});
if (html) {
el.innerHTML = html;
}
return el;
},
/**
* @function generateEmbed
* Generates Embed Container
*
* @param {string} source
* @param {string} html
* @returns
*/
generateEmbed: function generateEmbed(id, source, html) {
id = id || Embedo.utils.uuid();
var container = document.createElement('div');
container.setAttribute('id', id);
container.setAttribute('data-embedo-id', id);
container.setAttribute('data-embedo-source', source);
if (Embedo.utils.validateElement(html)) {
container.appendChild(html);
} else {
container.innerHTML = html || '';
}
return container;
},
/**
* @function generateScript
* Generates script tag element
*
* @param {string} source
* @returns HTMLElement
*/
generateScript: function generateScript(source) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = encodeURI(source);
script.setAttribute('async', '');
script.setAttribute('charset', 'utf-8');
return script;
},
/**
* @function validateElement
* Validates if passed argument is valid DOM element
*
* @param {object} obj
* @returns HTMLElement
*/
validateElement: function validateElement(obj) {
return typeof HTMLElement === 'object'
? obj instanceof window.HTMLElement
: obj &&
typeof obj === 'object' &&
obj !== null &&
obj.nodeType === 1 &&
typeof obj.nodeName === 'string';
},
/**
* @function sdkReady
* Checks when SDK global object is ready
*
* @param {string} type
* @param {function} callback
*/
sdkReady: function sdkReady(type, callback) {
callback = callback || function () {};
if (!Embedo.defaults.SOURCES[type]) {
return callback(new Error('unsupported_sdk_type'));
}
var counter = 0;
(function check() {
counter++;
if (counter > 15) {
return callback(new Error(type + ':sdk_not_available'));
}
if (window[Embedo.defaults.SOURCES[type].GLOBAL]) {
return callback(null, window[Embedo.defaults.SOURCES[type].GLOBAL]);
}
setTimeout(check, 10 * counter);
})();
},
/**
* @function querystring
* Object to Query String
*
* @param {object} obj
* @returns {string}
*/
querystring: function querystring(obj) {
var parts = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
parts.push(encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]));
}
}
return parts.join('&');
},
/**
* @function fetch
* JSONP XHR fetch
*
* @param {string} url
* @param {object} options
* @param {function} callback
*/
fetch: function fetch(url, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = options || {};
options.callback = options.callback || 'callback';
var target = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var jsonpCallback = 'jsonp_' + Embedo.utils.uuid();
url += (~url.indexOf('?') ? '&' : '?') + options.callback + '=' + encodeURIComponent(jsonpCallback);
url = url.replace('?&', '?');
window[jsonpCallback] = function (data) {
clear(jsonpCallback, script);
callback(null, data);
};
script.type = 'text/javascript';
script.defer = true;
script.charset = 'UTF-8';
script.onerror = function (err) {
clear(jsonpCallback, script);
return callback(err);
};
target.appendChild(script);
script.src = url;
function clear(jsonpCallback, script) {
try {
delete window[jsonpCallback];
} catch (e) {
window[jsonpCallback] = undefined;
}
if (script) {
target.removeChild(script);
script = undefined;
}
}
},
/**
* XHR HTTP Requests
*
* @param {string} url
* @param {object} options
* @param {Function} callback
*/
ajax: function ajax(url, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
callback = callback || function () {};
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 400) {
return callback(new Error(xhr.responseText || xhr.statusText));
}
try {
return callback(null, JSON.parse(xhr.responseText));
} catch (e) {
return callback(new Error('invalid_response'));
}
};
xhr.onerror = function (err) {
return callback(err);
};
xhr.open('GET', url);
xhr.send();
},
/**
* @function transform
* Cross Browser CSS Transformation
*
* @param {HTMLElement} element
* @param {string} props
*/
transform: function transform(element, props) {
if (!Embedo.utils.validateElement(element)) {
return;
}
element.style.webkitTransform = props;
element.style.MozTransform = props;
element.style.msTransform = props;
element.style.OTransform = props;
element.style.transform = props;
},
/**
* @function compute
* Computes property value of HTMLElement
*
* @param {HTMLElement} el
* @param {string} prop
* @param {Boolean} stylesheet
* @returns {Number}
*/
compute: function compute(el, prop, is_computed) {
if (!Embedo.utils.validateElement(el) || !prop) {
return;
}
var bounds = el.getBoundingClientRect();
var value = bounds[prop];
if (is_computed || !value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
value = document.defaultView.getComputedStyle(el, '').getPropertyValue(prop);
} else if (el.currentStyle) {
prop = prop.replace(/\-(\w)/g, function (m, p) {
return p.toUpperCase();
});
value = el.currentStyle[prop];
}
}
if (typeof value === 'string' && !/^\d+(\.\d+)?%$/.test(value)) {
value = value.replace(/[^\d.-]/g, '');
}
return isNaN(Number(value)) ? value : Number(value);
},
/**
* @method convertToPx
* Calculates approximate pixel value for vw, vh or % values
*
* @implements relative_px
* @implements percent_px
*/
convertToPx: function convertToPx(el, prop, value) {
if (!isNaN(Number(value))) {
return Number(value);
} else if (/^\d+(\.\d+)?%$/.test(value)) {
return percent_px(el, prop, value);
} else if (value.match(/(vh|vw)/)) {
var dimension = value.replace(/[0-9]/g, '');
return relative_px(dimension, value);
}
// Converts vw or vh to PX
function relative_px(type, value) {
var w = window,
d = document,
e = d.documentElement,
g = d.body,
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
if (type === 'vw') {
return (x * parseFloat(value)) / 100;
} else if (type === 'vh') {
return (y * parseFloat(value)) / 100;
} else {
return undefined;
}
}
// Converts % to PX
function percent_px(el, prop, percent) {
var parent_width = Embedo.utils.compute(el.parentNode, prop, true);
percent = parseFloat(percent);
return parent_width * (percent / 100);
}
},
/**
* @function watcher
*
* @param {string} Identifer
* @param {Function} Function to Trigger
* @param {integer} timer
*
* @returns {Function}
*/
watcher: function watcher(id, fn, timer) {
window.EMBEDO_WATCHER = window.EMBEDO_WATCHER || {};
window.EMBEDO_WATCHER[id] = window.EMBEDO_WATCHER[id] || {
id: id,
count: 0,
request: null
};
if (window.EMBEDO_WATCHER[id].count > 0 && window.EMBEDO_WATCHER[id].request) {
window.EMBEDO_WATCHER[id].count -= 1;
clearTimeout(window.EMBEDO_WATCHER[id].request);
}
window.EMBEDO_WATCHER[id].count += 1;
window.EMBEDO_WATCHER[id].request = setTimeout(function () {
window.EMBEDO_WATCHER[id].count -= 1;
if (window.EMBEDO_WATCHER[id].count === 0) {
fn.call();
}
}, timer);
return null;
},
/**
* @function dimensions
*
* @param {HTMLElement} el
* @param {string} width
* @param {string} height
*
* @returns {object{width,height}}
*/
dimensions: function dimensions(el, width, height) {
var el_width = Embedo.utils.compute(el, 'width');
width = width ? width : el_width > 0 ? el_width : Embedo.utils.compute(el.parentNode, 'width');
height = height
? height
: el_width > 0
? el_width / 1.5
: Embedo.utils.compute(el.parentNode, 'height');
return {
width: width,
height: height
};
},
/**
* @function centerize
* Align an element center in relation to parent div
*
* @param {HTMLElement} parent_el
* @param {HTMLElement} child_el
* @param {object} options
* @returns
*/
centerize: function centerize(parent_el, child_el, options) {
Embedo.log('info', 'centerize', parent_el, child_el, options);
if (!Embedo.utils.validateElement(parent_el) || !Embedo.utils.validateElement(child_el)) {
return;
}
options = options || {};
if (options.width) {
parent_el.style.width = options.width;
parent_el.style.maxWidth = options.width;
parent_el.style.marginLeft = 'auto';
parent_el.style.marginRight = 'auto';
}
if (options.height) {
parent_el.style.height = options.height;
parent_el.style.maxHeight = options.height;
}
child_el.style.display = '-moz-box';
child_el.style.display = '-ms-flexbox';
child_el.style.display = '-webkit-flex';
child_el.style.display = '-webkit-box';
child_el.style.display = 'flex';
child_el.style.textAlign = 'center';
child_el.style['justify-content'] = 'center';
child_el.style['align-items'] = 'center';
child_el.style.margin = '0 auto';
},
/**
* @function handleScriptValidation
*
* @param {string} url
*/
handleScriptValidation: function handleScriptValidation(url) {
if (!url) {
return;
}
url = url.split('#')[0];
var scripts = document.getElementsByTagName('script');
for (var i = scripts.length; i--; ) {
if (scripts[i].src === url) {
return true;
}
}
return false;
}
}),
writable: false,
enumerable: true,
configurable: false
});
/**
* Embedo Event Listeners
* @private
*
* @implements on
* @implements off
* @implements emit
*/
Object.defineProperties(Embedo.prototype, {
on: {
value: function (event, listener) {
if (typeof this.events[event] !== 'object') {
this.events[event] = [];
}
this.events[event].push(listener);
},
writable: false,
configurable: false
},
off: {
value: function (event, listener) {
var index;
if (typeof this.events[event] === 'object') {
index = this.events[event].indexOf(listener);
if (index > -1) {
this.events[event].splice(index, 1);
}
}
},
writable: false,
configurable: false
},
emit: {
value: function (event) {
var i,
listeners,
length,
args = [].slice.call(arguments, 1);
if (typeof this.events[event] === 'object') {
listeners = this.events[event].slice();
length = listeners.length;
for (i = 0; i < length; i++) {
listeners[i].apply(this, args);
}
}
},
writable: false,
configurable: false
},
once: {
value: function (event, listener) {
this.on(event, function g() {
this.off(event, g);
listener.apply(this, arguments);
});
},
writable: false,
configurable: false
}
});
/**
* @method init
* Primary Embedo initialization
*
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.init = function (options) {
Embedo.log('info', 'init', this.requests, options);
// Append enabled SDKs to DOM
Object.keys(Embedo.defaults.SOURCES).forEach(function (source) {
if (Embedo.defaults.SOURCES[source].SDK) {
appendSDK(source, options[source]);
}
});
this.domify();
/**
* @func appendSDK
* Injects SDK's to body
* @private
*
* @param {*} type
* @param {*} props
*/
function appendSDK(type, props) {
if (!type || !props) {
return;
}
var sdk =
props.sdk ||
Embedo.utils.replacer(Embedo.defaults.SOURCES[type.toLowerCase()].SDK, {
locale: props.locale || window.navigator.language || 'en_US'
});
if (!Embedo.utils.handleScriptValidation(sdk)) {
if (props && typeof props === 'object') {
sdk += (type === 'facebook' ? '#' : '?') + Embedo.utils.querystring(props);
}
document.body.appendChild(Embedo.utils.generateScript(sdk));
}
}
};
/**
* @method domify
* Replaces "data-embedo-*" elements during initialization.
*/
Embedo.prototype.domify = function domify() {
var embedos = document.querySelectorAll('[data-embedo-url]');
[].forEach.call(
embedos,
function (embedo_el) {
var options = Object.keys(embedo_el.dataset || {}).reduce(function (acc, cur) {
if (cur.indexOf('embedo') !== -1) {
var option = Embedo.utils.camelToSnake(cur).replace('embedo-', '');
acc[option] = embedo_el.dataset[cur];
}
return acc;
}, {});
this.render(embedo_el, options.url, options);
}.bind(this)
);
};
/**
* @method facebook
* Facebook embed prototype
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.facebook = function facebook(id, element, url, options, callback) {
var type, fb_html_class;
var globalOptions = this.options.facebook || {};
if (/^([^\/?].+\/)?post|photo(s|\.php)[\/?].*$/gm.test(url)) {
type = url.match(/comment_id|reply_comment_id/) ? 'comment' : 'post';
} else if (/^([^\/?].+\/)?video(s|\.php)[\/?].*$/gm.test(url)) {
type = 'video';
}
if (type && type.match(/post|video/)) {
var embed_uri = Embedo.utils.replacer(Embedo.defaults.SOURCES.facebook.oEmbed, {
version: globalOptions.version || 'v8.0',
type: type
});
var query = Embedo.utils.merge(
{
url: encodeURI(url),
access_token: globalOptions.access_token,
omitscript: true
},
options,
Embedo.defaults.RESTRICTED
);
if ('width' in options || 'maxwidth' in options) {
query.maxwidth = options.maxwidth || options.width;
}
embed_uri += '?' + Embedo.utils.querystring(query);
Embedo.utils.fetch(embed_uri, function (error, content) {
if (error) {
Embedo.log('error', 'facebook', error);
return callback(error);
}
handleFacebookEmbed(content.html);
});
} else {
if (type === 'comment' || url.match(/comment_id|reply_comment_id/)) {
fb_html_class = 'fb-comment-embed';
options['data-numposts'] = options['data-numposts'] || 5;
} else if (url.match(/plugins\/comments/)) {
fb_html_class = 'fb-comments';
} else {
fb_html_class = 'fb-page';
options['data-height'] = options['data-height'] || options.maxheight || options.height || 500;
}
var fb_html = Embedo.utils.generateElement(
'div',
Embedo.utils.merge(
{
class: fb_html_class,
'data-href': url,
'data-width': options['data-width'] || options.maxwidth || options.width || 350
},
options
)
);
fb_html.removeAttribute('width');
fb_html.removeAttribute('height');
handleFacebookEmbed(fb_html);
}
function handleFacebookEmbed(html) {
var container = Embedo.utils.generateEmbed(id, 'facebook', html);
element.appendChild(container);
facebookify(
element,
container,
{
id: id,
url: url,
strict: options.strict,
width: options.width,
height: options.height,
centerize: options.centerize
},
function (err, result) {
if (err) {
return callback(err);
}
callback(null, {
id: id,
el: element,
width: result.width,
height: result.height
});
}
);
}
};
/**
* Twitter embed prototype
* @method twitter
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.twitter = function twitter(id, element, url, options, callback) {
var embed_uri = Embedo.defaults.SOURCES.twitter.oEmbed;
var query = Embedo.utils.merge(
{
url: encodeURI(url),
omit_script: 1
},
options,
Embedo.defaults.RESTRICTED
);
if ('width' in options || 'maxwidth' in options) {
query.maxwidth = options.maxwidth || options.width;
}
if ('height' in options || 'maxheight' in options) {
query.maxheight = options.maxheight || options.height;
}
embed_uri += '?' + Embedo.utils.querystring(query);
Embedo.utils.fetch(embed_uri, function (error, content) {
if (error) {
Embedo.log('error', 'twitter', error);
return callback(error);
}
var container = Embedo.utils.generateEmbed(id, 'twitter', content.html);
element.appendChild(container);
twitterify(
element,
container,
{
id: id,
url: url,
strict: options.strict,
width: options.width,
height: options.height,
centerize: options.centerize
},
function (err, result) {
if (err) {
return callback(err);
}
callback(null, {
id: id,
el: element,
width: result.width,
height: result.height
});
}
);
});
};
/**
* @method instagram
* Instagram embed prototype
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.instagram = function (id, element, url, options, callback) {
var globalOptions = this.options.instagram || {};
var embed_uri = Embedo.utils.replacer(Embedo.defaults.SOURCES.instagram.oEmbed, {
version: globalOptions.version || 'v8.0'
});
var query = Embedo.utils.merge(
{
url: encodeURI(url),
access_token: globalOptions.access_token,
omitscript: true,
hidecaption: true
},
options,
Embedo.defaults.RESTRICTED
);
if ('width' in options || 'maxwidth' in options) {
options.width = options.maxwidth ? options.maxwidth : options.width;
if (options.width > 320) {
query.maxwidth = options.width;
}
}
embed_uri += '?' + Embedo.utils.querystring(query);
var method = options.jsonp ? 'jsonp' : 'ajax';
Embedo.utils[method](
embed_uri,
function (err, content) {
if (err) {
Embedo.log('error', 'instagram', err);
// If oembed or instagram embed script is unavailable.
if (options.jsonp === undefined || options.jsonp === null) {
var extracted_url = url.match(Embedo.defaults.SOURCES.instagram.REGEX);
url = extracted_url && extracted_url.length > 0 ? extracted_url[0].replace(/\/$/, '') : url;
return this.iframe(id, element, url + '/embed/', options, callback);
}
return callback(err);
}
var container = Embedo.utils.generateEmbed(id, 'instagram', content.html);
element.appendChild(container);
instagramify(
element,
container,
{
id: id,
url: url,
strict: options.strict,
width: options.width,
height: options.height,
centerize: options.centerize
},
function (err, result) {
if (err) {
return callback(err);
}
callback(null, {
id: id,
el: element,
width: result.width,
height: result.height
});
}
);
}.bind(this)
);
};
/**
* @method youtube
* YouTube embed prototype
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.youtube = function (id, element, url, options, callback) {
if (!getYTVideoID(url)) {
Embedo.log('error', 'youtube', 'Unable to detect Youtube video id.');
return callback('Unable to detect Youtube video id.');
}
var youtube_uri = Embedo.defaults.SOURCES.youtube.oEmbed + getYTVideoID(url);
youtube_uri +=
'?' +
Embedo.utils.querystring(
Embedo.utils.merge(
{
modestbranding: 1,
autohide: 1,
showinfo: 0
},
options,
Embedo.defaults.RESTRICTED
)
);
this.iframe(id, element, youtube_uri, options, callback);
/**
* @func getYTVideoID
* @private
*
* @param {string} url
* @returns {String|Boolean}
*/
function getYTVideoID(url) {
var regexp = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;
var match = url.match(regexp);
return match && match.length === 2 ? match[1] : false;
}
};
/**
* @method vimeo
* Vimeo embed prototype
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.vimeo = function (id, element, url, options, callback) {
var size = Embedo.utils.dimensions(element, options.width, options.height);
var embed_options = Embedo.utils.merge(
{
url: url,
width: size.width,
height: size.height,
autohide: 1
},
options,
Embedo.defaults.RESTRICTED
);
var embed_uri = Embedo.defaults.SOURCES.vimeo.oEmbed + '?' + Embedo.utils.querystring(embed_options);
Embedo.utils.fetch(embed_uri, function (error, content) {
if (error) {
Embedo.log('error', 'vimeo', error);
return callback(error);
}
var container = Embedo.utils.generateEmbed(id, 'vimeo', content.html);
element.appendChild(container);
callback(null, {
id: id,
el: element,
width: size.width,
height: size.height
});
});
};
/**
* @method pinterest
* Pinterest Embed
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.pinterest = function (id, element, url, options, callback) {
var size = Embedo.utils.dimensions(element, options.width, options.height);
var pin_size = size.width > 600 ? 'large' : size.width < 345 ? 'small' : 'medium';
var pin_el = Embedo.utils.generateElement(
'a',
Embedo.utils.merge(
{
href: url,
'data-pin-do': options['data-pin-do'] || 'embedPin',
'data-pin-lang': options['data-pin-lang'] || 'en',
'data-pin-width': pin_size
},
options
)
);
var container = Embedo.utils.generateEmbed(id, 'pinterest', pin_el);
element.appendChild(container);
pinterestify(
element,
container,
{
id: id,
url: url,
strict: options.strict,
width: options.width,
height: options.height,
centerize: options.centerize
},
function (err, result) {
if (err) {
Embedo.log('error', 'pinterest', err);
return callback(err);
}
callback(null, {
id: id,
el: element,
width: result.width,
height: result.height
});
}
);
};
/**
* @method github
* Embed github URLs (gist) to DOM
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.github = function github(id, element, url, options, callback) {
var size = Embedo.utils.dimensions(element, options.width, options.height);
var iframe = Embedo.utils.generateElement(
'iframe',
Embedo.utils.merge(
{
width: size.width,
height: size.height
},
options,
Embedo.defaults.RESTRICTED
)
);
var container = Embedo.utils.generateEmbed(id, 'github', iframe);
element.appendChild(container);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(
'<body><style type="text/css">body,html{margin:0;padding:0;border-radius:3px;}' +
'.gist .gist-file{margin:0 !important;padding:0;}</style>' +
'<script src="' +
url +
'"></script>' +
'</body>'
);
iframe.contentWindow.document.close();
iframe.onerror = function (err) {
callback(err);
};
iframe.addEventListener('load', function (event) {
callback(null, {
id: id,
el: element,
event: event,
width: Embedo.utils.compute(container, 'width'),
height: Embedo.utils.compute(container, 'height')
});
});
};
/**
* @method soundcloud
* SoundCloud Embed Player (api-web) prototype
*
* @see https://developers.soundcloud.com/docs/oembed
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.soundcloud = function (id, element, url, options, callback) {
if (options.hasOwnProperty('width') && options.width) {
options.maxwidth = options.maxwidth || options.width || '100%';
}
if (options.hasOwnProperty('height') && options.height) {
options.maxheight = options.maxheight || options.height;
}
var size = Embedo.utils.dimensions(element, options.maxwidth, options.maxheight);
var embed_options = Embedo.utils.merge(
{
url: encodeURI(url),
format: 'js' // Defaults JSONP
},
options,
Embedo.defaults.RESTRICTED
);
var embed_uri = Embedo.defaults.SOURCES.soundcloud.oEmbed + '?' + Embedo.utils.querystring(embed_options);
Embedo.utils.fetch(embed_uri, function (error, content) {
if (error) {
Embedo.log('error', 'soundcloud', error);
return callback(error);
}
var container = Embedo.utils.generateEmbed(id, 'soundcloud', content.html);
element.appendChild(container);
callback(null, {
id: id,
el: element,
width: size.width,
height: size.height
});
});
};
/**
* @method iframe
* Embed URLs to HTML5 frame prototype
*
* @param {number} id
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.iframe = function (id, element, url, options, callback) {
var fragment = document.createDocumentFragment();
var size = Embedo.utils.dimensions(element, options.width, options.height);
var extension = (url.substr(url.lastIndexOf('.')) || '').replace('.', '').toLowerCase();
var mimes = {
csv: 'text/csv',
pdf: 'application/pdf',
gif: 'image/gif',
js: 'application/javascript',
json: 'application/json',
xhtml: 'application/xhtml+xml',
pps: 'application/vnd.ms-powerpoint',
ppsx: 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
xml: 'application/xml',
ogg: 'video/ogg',
mp4: 'video/mp4',
webm: 'video/webm',
html: 'text/html'
};
var mimetype = mimes[extension] || mimes.html;
var has_video = extension.match(/(mp4|ogg|webm|ogv|ogm)/);
var el_type = has_video ? 'video' : options.tagName || 'embed';
var override = Embedo.utils.merge({}, options, Embedo.defaults.RESTRICTED);
var embed_el = Embedo.utils.generateElement(
el_type,
Embedo.utils.merge(
{
type: mimetype,
src: url,
width: size.width,
height: size.height
},
override
)
);
fragment.appendChild(Embedo.utils.generateEmbed(id, 'iframe', embed_el));
element.appendChild(fragment);
if (el_type === 'video') {
setTimeout(function () {
callback(null, {
id: id,
el: element,
width: Embedo.utils.compute(embed_el, 'width'),
height: Embedo.utils.compute(embed_el, 'height')
});
}, 250);
} else {
embed_el.onerror = function (err) {
callback(err);
};
embed_el.addEventListener('load', function (event) {
callback(null, {
id: id,
el: element,
event: event,
width: Embedo.utils.compute(embed_el, 'width'),
height: Embedo.utils.compute(embed_el, 'height')
});
});
}
};
/**
* @method render
* Renders an embedo instance
*
* @name load
* @param {HTMLElement} element
* @param {string} url
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.render = function (element, url, options, callback) {
Embedo.log('info', 'render', element, url, options);
options = options || {};
callback = callback || function () {};
if (!element || !Embedo.utils.validateElement(element)) {
Embedo.log('info', 'render', '`element` is either missing or invalid');
return this.emit('error', new Error('element_is_missing'));
}
if (typeof url !== 'string') {
return this.emit('error', new Error('invalid_url_string'));
}
if (!url || !Embedo.utils.validateURL(url)) {
Embedo.log('info', 'render', '`url` is either missing or invalid');
return this.emit('error', new Error('invalid_or_missing_url'));
}
var source = getURLSource(url);
if (!source) {
Embedo.log('info', 'render', new Error('Invalid or Unsupported URL'));
return this.emit('error', new Error('url_not_supported'));
}
if (!this[source]) {
Embedo.log('info', 'render', new Error('Requested source is not implemented or missing.'));
return this.emit('error', new Error('unrecognised_url'));
}
if ('width' in options && options.width) {
options.width = Embedo.utils.convertToPx(element, 'width', options.width);
}
if ('height' in options && options.height) {
options.height = Embedo.utils.convertToPx(element, 'height', options.height);
}
var id = Embedo.utils.uuid();
var request = {
id: id,
el: element,
source: source,
url: url,
attributes: options
};
this.requests.push(request);
this.emit('watch', 'load', request);
this[source](
id,
element,
url,
options,
function (err, data) {
if (err) {
this.emit('error', err);
return callback(err);
}
data.url = request.url;
data.source = request.source;
data.options = request.attributes;
this.emit('watch', 'loaded', data);
callback(null, data);
}.bind(this)
);
/**
* @function getURLSource
* Checks Source from URI
*
* @param {string} url
* @returns {string}
*/
function getURLSource(url) {
var urlRegExp = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
var sources = Object.keys(Embedo.defaults.SOURCES) || [];
if (!urlRegExp.test(url)) {
return null;
}
var matched_source = sources
.filter(function (source) {
if (Embedo.defaults.SOURCES[source] && url.match(Embedo.defaults.SOURCES[source].REGEX)) {
return source;
}
})
.filter(Boolean);
return matched_source && matched_source.length ? matched_source[0] : 'iframe';
}
};
/**
* @method load
* Loads single or multiple embedo instances
*
* @name load
* @param {HTMLElement} element
* @param {String|Array} urls
* @param {object} options Optional parameters.
* @return callback
*/
Embedo.prototype.load = function (element, urls, options) {
Embedo.log('info', 'load', element, urls, options);
options = options || {};
var observer = new Embedo.utils.observer();
if (!element || !Embedo.utils.validateElement(element)) {
Embedo.log('info', 'load', '`element` is either missing or invalid');
this.emit('error', new Error('element_is_missing'));
} else {
if (urls instanceof Array) {
var reqs = {
failed: [],
finished: []
};
var jobs = urls.map(
function (url) {
return function (done) {
this.render(element, url, options, function (err, data) {
if (err) {
reqs.failed.push(err);
return done(err);
}
reqs.finished.push(data);
done(null, data);
});
}.bind(this);
}.bind(this)
);
Embedo.utils.sequencer.apply(this, jobs).then(function () {
if (reqs.failed.length > 0) {
return observer.reject(reqs.failed);
}
observer.resolve(reqs.finished);
});
} else if (typeof urls === 'string') {
this.render(element, urls, options, function (err, data) {
if (err) {
return observer.reject(err);
}
observer.resolve(data);
});
} else {
this.emit('error', new Error('invalid_url_string'));
}
}
return observer;
};
/**
* @method refresh
* Refresh single or all embedo instances
*
* @param {object} element
*/
Embedo.prototype.refresh = function (element) {
Embedo.log('info', 'refresh', this.requests, element);
if (this.requests.length === 0) {
return;
}
this.requests.forEach(
function (request) {
if (!request.el) {
return;
}
if (request.source === 'iframe') {
return this.emit('refresh', request, {
width: Embedo.utils.compute(request.el, 'width'),
height: Embedo.utils.compute(request.el, 'height')
});
}
if (element) {
if (!Embedo.utils.validateElement(element)) {
return;
}
if (element === request.el) {
automagic(
request.el,
document.getElementById(request.id),
request.attributes,
function (err, data) {
if (data) {
this.emit('refresh', request, data);
}
}.bind(this)
);
}
} else {
automagic(
request.el,
document.getElementById(request.id),
request.attributes,
function (err, data) {
if (data) {
this.emit('refresh', request, data);
}
}.bind(this)
);
}
}.bind(this)
);
return this;
};
/**
* @method destroy
* Destroy an/all instance(s) of embedo
*
* @param {object} element
*/
Embedo.prototype.destroy = function (element) {
Embedo.log('warn', 'destroy', this.requests, element);
if (this.requests.length === 0) {
return;
}
var removed = [];
this.requests.forEach(
function (request) {
if (!request.el || !Embedo.utils.validateElement(request.el)) {
return;
}
if (element) {
if (!Embedo.utils.validateElement(element)) {
return;
}
if (element === request.el) {
if (document.getElementById(request.id)) {
document.getElementById(request.id).remove();
}
removed.push(request.id);
this.emit('destroy', request);
}
} else {
if (document.getElementById(request.id)) {
document.getElementById(request.id).remove();
}
removed.push(request.id);
this.emit('destroy', request);
}
}.bind(this)
);
this.requests = this.requests.filter(function (request) {
return removed.indexOf(request.id) < 0;
});
return this;
};
/**
* @function facebookify
* Parses Facebook SDK
*
* @param {HTMLElement} parentNode
* @param {HTMLElement} childNode
* @param {object} options
*/
function facebookify(parentNode, childNode, options, callback) {
Embedo.utils.sdkReady('facebook', function (err) {
if (err) {
return callback(err);
}
window.FB.XFBML.parse(parentNode);
window.FB.Event.subscribe('xfbml.render', function () {
// First state will be `parsed` and then `rendered` to acknowledge embed.
if (childNode.firstChild) {
if (options.centerize !== false) {
Embedo.utils.centerize(parentNode, childNode, options);
}
if (childNode.firstChild.getAttribute('fb-xfbml-state') === 'rendered') {
automagic(parentNode, childNode, options, callback);
}
}
});
});
}
/**
* @function twitterify
* Parses Twitter SDK
*
* @param {HTMLElement} parentNode
* @param {HTMLElement} childNode
* @param {object} options
*/
function twitterify(parentNode, childNode, options, callback) {
Embedo.utils.sdkReady('twitter', function (err) {
if (err) {
return callback(err);
}
window.twttr.widgets.load(childNode);
window.twttr.events.bind('rendered', function (event) {
if (
childNode.firstChild &&
childNode.firstChild.getAttribute('id') === event.target.getAttribute('id')
) {
if (options.centerize !== false) {
Embedo.utils.centerize(parentNode, childNode, options);
}
automagic(parentNode, childNode, options, callback);
}
});
});
}
/**
* @function instagramify
* Parses Instagram SDK
*
* @param {HTMLElement} parentNode
* @param {HTMLElement} childNode
* @param {object} options
*/
function instagramify(parentNode, childNode, options, callback) {
Embedo.utils.sdkReady('instagram', function (err) {
if (err) {
return callback(err);
}
if (!window.instgrm.Embeds || !window.instgrm.Embeds) {
return callback(new Error('instagram_sdk_missing'));
}
window.instgrm.Embeds.process(childNode);
var instagram_embed_timer = setInterval(handleInstagramRendered, 250);
function handleInstagramRendered() {
if (childNode.firstChild && childNode.firstChild.className.match(/instagram-media-rendered/)) {
clearInterval(instagram_embed_timer);
if (options.centerize !== false) {
Embedo.utils.centerize(parentNode, childNode, options);
}
return automagic(parentNode, childNode, options, callback);
}
}
});
}
/**
* @function pinterestify
* Parses Pinterest SDK
*
* @param {HTMLElement} parentNode
* @param {HTMLElement} childNode
* @param {object} options
*/
function pinterestify(parentNode, childNode, options, callback) {
Embedo.utils.sdkReady('pinterest', function (err) {
if (err) {
return callback(err);
}
if (!window.PinUtils || !window.PinUtils || !childNode || !childNode.firstChild) {
return callback(new Error('pinterest_sdk_missing'));
}
setTimeout(function () {
if (!childNode.querySelector('[data-pin-href]')) {
window.PinUtils.build(childNode);
}
var pinterest_embed_timer_count = 0;
var pinterest_embed_timer = setInterval(function () {
pinterest_embed_timer_count += 1;
if (childNode.querySelector('[data-pin-href]')) {
clearInterval(pinterest_embed_timer);
if (options.centerize !== false) {
Embedo.utils.centerize(parentNode, childNode, options);
}
return automagic(parentNode, childNode, options, callback);
} else if (pinterest_embed_timer_count >= 20) {
clearInterval(pinterest_embed_timer);
return callback(new Error('pinterest_embed_failed'));
}
}, 250);
}, 750);
});
}
/**
* @function automagic
* Automagic - Scales and resizes embed container
*
* @param {HTMLElement} parentNode
* @param {HTMLElement} childNode
* @param {object} options
*/
function automagic(parentNode, childNode, options, callback) {
Embedo.log('info', 'automagic', parentNode, childNode, options);
options = options || {};
callback = callback || function () {};
if (!Embedo.utils.validateElement(parentNode) || !Embedo.utils.validateElement(childNode)) {
return callback(new Error('HTMLElement does not exist in DOM.'));
}
Embedo.utils.watcher(
options.id || Embedo.utils.uuid(),
function () {
var parent = {
width: options.width || Embedo.utils.compute(parentNode, 'width'),
height: options.height || Embedo.utils.compute(parentNode, 'height')
};
var child = {
width: Embedo.utils.compute(childNode, 'width'),
height: Embedo.utils.compute(childNode, 'height')
};
if (options.strict) {
return callback(null, {
width: parent.width,
height: parent.height
});
}
// Odd case when requested height is beyond limit of third party
// Only apply when fixed width and heights are provided
if (options.width && options.height) {
var isOverflowing = child.width > parent.width || child.height > parent.height;
if (options.width) {
childNode.style.width = options.width + 'px';
}
if (options.height) {
childNode.style.height = options.height + 'px';
}
if (isOverflowing) {
var scale = Math.min(parent.width / child.width, parent.height / child.height);
Embedo.utils.transform(childNode, 'scale(' + scale + ')');
}
}
callback(null, {
width: parent.width,
height: parent.height
});
},
500
);
}
return Embedo;
});
});
$(document).on('ready pjax:scriptcomplete', function () {
$('oembed').each(function (i, item) {
if ($(this).find(".svgcontainer").length == 0) {
$(this).append("\n <div class=\"svgcontainer\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 26 26\">\n <polygon class=\"play-btn__svg\" points=\"9.33 6.69 9.33 19.39 19.3 13.04 9.33 6.69\"/>\n <path class=\"play-btn__svg\" d=\"M26,13A13,13,0,1,1,13,0,13,13,0,0,1,26,13ZM13,2.18A10.89,10.89,0,1,0,23.84,13.06,10.89,10.89,0,0,0,13,2.18Z\"/>\n </svg>\n </div>");
}
});
$('oembed').off('click.embeddable');
$('oembed').on('click.embeddable', function () {
window.embedo = window.embedo || new embedo({
facebook: true,
twitter: true,
instagram: true,
pinterest: true,
youtube: true,
vimeo: true,
github: true,
soundcloud: true,
googlemaps: true
});
$(this).find(".svgcontainer").remove();
var url = $(this).attr('url');
window.embedo.load(this, url).done(function (result) {
console.ls.log(result);
}).fail(function (result) {
console.ls.error(result);
});
});
});
}));