Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

opentok-layout-js

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opentok-layout-js - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

.eslintignore

2

bower.json
{
"name": "opentok-layout-js",
"version": "2.1.0",
"version": "3.0.0",
"homepage": "https://github.com/aullman/opentok-layout-js",

@@ -5,0 +5,0 @@ "authors": [

@@ -0,1 +1,104 @@

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["initLayoutContainer"] = factory();
else
root["initLayoutContainer"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*!

@@ -10,3 +113,3 @@ * opentok-layout-js (http://github.com/aullman/opentok-layout-js)

* @License: Released under the MIT license (http://opensource.org/licenses/MIT)
**/
* */

@@ -17,392 +120,429 @@ // in CommonJS context, this should be a `require()`d dependency.

var getLayout = __webpack_require__(1);
var layout = __webpack_require__(2);
(function($) {
function css(el, propertyName, value) {
if (value) {
// We are setting one css property
el.style[propertyName] = value;
} else if (typeof propertyName === 'object') {
// We are setting several CSS properties at once
Object.keys(propertyName).forEach(function(key) {
css(el, key, propertyName[key]);
});
} else {
// We are getting the css property
var computedStyle = getComputedStyle(el);
var currentValue = computedStyle.getPropertyValue(propertyName);
module.exports = function initLayoutContainer(container, opts) {
container = typeof container === 'string' ? document.querySelector(container) : container;
if (!(typeof HTMLElement === 'undefined' || container instanceof HTMLElement) && !opts) {
// container is actually the options
opts = container;
} else if (!opts) {
opts = {};
}
if (currentValue === '') {
currentValue = el.style[propertyName];
}
return {
layout: layout.bind(this, container, opts),
getLayout: getLayout.bind(this, opts)
};
};
return currentValue;
}
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var getBestDimensions = function getBestDimensions(minRatio, maxRatio, Width, Height, count) {
var maxArea = void 0;
var targetCols = void 0;
var targetRows = void 0;
var targetHeight = void 0;
var targetWidth = void 0;
var tWidth = void 0;
var tHeight = void 0;
var tRatio = void 0;
// Iterate through every possible combination of rows and columns
// and see which one has the least amount of whitespace
for (var i = 1; i <= count; i += 1) {
var cols = i;
var rows = Math.ceil(count / cols);
// Try taking up the whole height and width
tHeight = Math.floor(Height / rows);
tWidth = Math.floor(Width / cols);
tRatio = tHeight / tWidth;
if (tRatio > maxRatio) {
// We went over decrease the height
tRatio = maxRatio;
tHeight = tWidth * tRatio;
} else if (tRatio < minRatio) {
// We went under decrease the width
tRatio = minRatio;
tWidth = tHeight / tRatio;
}
function height(el) {
if (el.offsetHeight > 0) {
return el.offsetHeight + 'px';
}
return css(el, 'height');
var area = tWidth * tHeight * count;
// If this width and height takes up the most space then we're going with that
if (maxArea === undefined || area > maxArea) {
maxArea = area;
targetHeight = tHeight;
targetWidth = tWidth;
targetCols = cols;
targetRows = rows;
}
function width(el) {
if (el.offsetWidth > 0) {
return el.offsetWidth + 'px';
}
return css(el, 'width');
}
function defaults(custom, defaults) {
var res = {};
Object.keys(defaults).forEach(function(key) {
if (custom.hasOwnProperty(key)) {
res[key] = custom[key];
} else {
res[key] = defaults[key];
}
});
return res;
}
}
return {
maxArea: maxArea,
targetCols: targetCols,
targetRows: targetRows,
targetHeight: targetHeight,
targetWidth: targetWidth,
ratio: targetHeight / targetWidth
};
};
var positionElement = function positionElement(elem, x, y, width, height, animate) {
var targetPosition = {
left: x + 'px',
top: y + 'px',
width: width + 'px',
height: height + 'px'
};
module.exports = function (opts, ratios) {
var _opts$maxRatio = opts.maxRatio,
maxRatio = _opts$maxRatio === undefined ? 3 / 2 : _opts$maxRatio,
_opts$minRatio = opts.minRatio,
minRatio = _opts$minRatio === undefined ? 9 / 16 : _opts$minRatio,
_opts$fixedRatio = opts.fixedRatio,
fixedRatio = _opts$fixedRatio === undefined ? false : _opts$fixedRatio,
_opts$containerWidth = opts.containerWidth,
containerWidth = _opts$containerWidth === undefined ? 640 : _opts$containerWidth,
_opts$containerHeight = opts.containerHeight,
containerHeight = _opts$containerHeight === undefined ? 480 : _opts$containerHeight;
var fixAspectRatio = function () {
var sub = elem.querySelector('.OT_root');
if (sub) {
// If this is the parent of a subscriber or publisher then we need
// to force the mutation observer on the publisher or subscriber to
// trigger to get it to fix it's layout
var oldWidth = sub.style.width;
sub.style.width = width + 'px';
// sub.style.height = height + 'px';
sub.style.width = oldWidth || '';
}
};
var count = ratios.length;
var dimensions = void 0;
if (animate && $) {
$(elem).stop();
$(elem).animate(targetPosition, animate.duration || 200, animate.easing || 'swing',
function () {
fixAspectRatio();
if (animate.complete) animate.complete.call(this);
});
} else {
css(elem, targetPosition);
if (!elem.classList.contains('ot-layout')) {
elem.classList.add('ot-layout');
}
if (!fixedRatio) {
dimensions = getBestDimensions(minRatio, maxRatio, containerWidth, containerHeight, count);
} else {
// Use the ratio of the first video element we find to approximate
var ratio = ratios.length > 0 ? ratios[0] : null;
dimensions = getBestDimensions(ratio, ratio, containerWidth, containerHeight, count);
}
// Loop through each stream in the container and place it inside
var x = 0;
var y = 0;
var rows = [];
var row = void 0;
var boxes = [];
// Iterate through the children and create an array with a new item for each row
// and calculate the width of each row so that we know if we go over the size and need
// to adjust
for (var i = 0; i < ratios.length; i += 1) {
if (i % dimensions.targetCols === 0) {
// This is a new row
row = {
ratios: [],
width: 0,
height: 0
};
rows.push(row);
}
var _ratio = ratios[i];
row.ratios.push(_ratio);
var targetWidth = dimensions.targetWidth;
var targetHeight = dimensions.targetHeight;
// If we're using a fixedRatio then we need to set the correct ratio for this element
if (fixedRatio) {
targetWidth = targetHeight / _ratio;
}
row.width += targetWidth;
row.height = targetHeight;
}
// Calculate total row height adjusting if we go too wide
var totalRowHeight = 0;
var remainingShortRows = 0;
for (var _i = 0; _i < rows.length; _i += 1) {
row = rows[_i];
if (row.width > containerWidth) {
// Went over on the width, need to adjust the height proportionally
row.height = Math.floor(row.height * (containerWidth / row.width));
row.width = containerWidth;
} else if (row.width < containerWidth) {
remainingShortRows += 1;
}
totalRowHeight += row.height;
}
if (totalRowHeight < containerHeight && remainingShortRows > 0) {
// We can grow some of the rows, we're not taking up the whole height
var remainingHeightDiff = containerHeight - totalRowHeight;
totalRowHeight = 0;
for (var _i2 = 0; _i2 < rows.length; _i2 += 1) {
row = rows[_i2];
if (row.width < containerWidth) {
// Evenly distribute the extra height between the short rows
var extraHeight = remainingHeightDiff / remainingShortRows;
if (extraHeight / row.height > (containerWidth - row.width) / row.width) {
// We can't go that big or we'll go too wide
extraHeight = Math.floor((containerWidth - row.width) / row.width * row.height);
}
fixAspectRatio();
};
row.width += Math.floor(extraHeight / row.height * row.width);
row.height += extraHeight;
remainingHeightDiff -= extraHeight;
remainingShortRows -= 1;
}
totalRowHeight += row.height;
}
}
// vertical centering
y = (containerHeight - totalRowHeight) / 2;
// Iterate through each row and place each child
for (var _i3 = 0; _i3 < rows.length; _i3 += 1) {
row = rows[_i3];
// center the row
var rowMarginLeft = (containerWidth - row.width) / 2;
x = rowMarginLeft;
var _targetHeight = void 0;
for (var j = 0; j < row.ratios.length; j += 1) {
var _ratio2 = row.ratios[j];
var getVideoRatio = function(elem) {
if (!elem) {
return 3 / 4;
var _targetWidth = dimensions.targetWidth;
_targetHeight = row.height;
// If we're using a fixedRatio then we need to set the correct ratio for this element
if (fixedRatio) {
_targetWidth = Math.floor(_targetHeight / _ratio2);
}
var video = elem.querySelector('video');
if (video && video.videoHeight && video.videoWidth) {
return video.videoHeight / video.videoWidth;
} else if (elem.videoHeight && elem.videoWidth) {
return elem.videoHeight / elem.videoWidth;
}
return 3 / 4;
boxes.push({
aspectRatio: _ratio2,
left: x,
top: y,
width: _targetWidth,
height: _targetHeight
});
x += _targetWidth;
}
y += _targetHeight;
}
return boxes;
};
var getCSSNumber = function (elem, prop) {
var cssStr = css(elem, prop);
return cssStr ? parseInt(cssStr, 10) : 0;
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
// Really cheap UUID function
var cheapUUID = function() {
return (Math.random() * 100000000).toFixed(0);
};
"use strict";
var getHeight = function (elem) {
var heightStr = height(elem);
return heightStr ? parseInt(heightStr, 10) : 0;
};
var getWidth = function (elem) {
var widthStr = width(elem);
return widthStr ? parseInt(widthStr, 10) : 0;
};
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var arrange = function arrange(children, Width, Height, offsetLeft, offsetTop, fixedRatio,
minRatio, maxRatio, animate) {
var count = children.length,
dimensions;
var getLayout = __webpack_require__(1);
var getBestDimensions = function getBestDimensions(minRatio, maxRatio) {
var maxArea,
targetCols,
targetRows,
targetHeight,
targetWidth,
tWidth,
tHeight,
tRatio;
function css(el, propertyName, value) {
if (value) {
// We are setting one css property
el.style[propertyName] = value;
return NaN;
}
if ((typeof propertyName === 'undefined' ? 'undefined' : _typeof(propertyName)) === 'object') {
// We are setting several CSS properties at once
Object.keys(propertyName).forEach(function (key) {
css(el, key, propertyName[key]);
});
return NaN;
}
// We are getting the css property
var computedStyle = getComputedStyle(el);
var currentValue = computedStyle.getPropertyValue(propertyName);
// Iterate through every possible combination of rows and columns
// and see which one has the least amount of whitespace
for (var i=1; i <= count; i++) {
var cols = i;
var rows = Math.ceil(count / cols);
if (currentValue === '') {
currentValue = el.style[propertyName];
}
// Try taking up the whole height and width
tHeight = Math.floor( Height/rows );
tWidth = Math.floor(Width/cols);
return currentValue;
}
tRatio = tHeight/tWidth;
if (tRatio > maxRatio) {
// We went over decrease the height
tRatio = maxRatio;
tHeight = tWidth * tRatio;
} else if (tRatio < minRatio) {
// We went under decrease the width
tRatio = minRatio;
tWidth = tHeight / tRatio;
}
var filterDisplayNone = function filterDisplayNone(element) {
return css(element, 'display') !== 'none';
};
var area = (tWidth*tHeight) * count;
function height(el) {
if (el.offsetHeight > 0) {
return el.offsetHeight + 'px';
}
return css(el, 'height');
}
// If this width and height takes up the most space then we're going with that
if (maxArea === undefined || (area > maxArea)) {
maxArea = area;
targetHeight = tHeight;
targetWidth = tWidth;
targetCols = cols;
targetRows = rows;
}
}
return {
maxArea: maxArea,
targetCols: targetCols,
targetRows: targetRows,
targetHeight: targetHeight,
targetWidth: targetWidth,
ratio: targetHeight / targetWidth
};
};
function width(el) {
if (el.offsetWidth > 0) {
return el.offsetWidth + 'px';
}
return css(el, 'width');
}
if (!fixedRatio) {
dimensions = getBestDimensions(minRatio, maxRatio);
} else {
// Use the ratio of the first video element we find to approximate
var ratio = getVideoRatio(children.length > 0 ? children[0] : null);
dimensions = getBestDimensions(ratio, ratio);
}
var positionElement = function positionElement(elem, x, y, w, h, animate) {
var _this = this;
// Loop through each stream in the container and place it inside
var x = 0,
y = 0,
rows = [],
row;
// Iterate through the children and create an array with a new item for each row
// and calculate the width of each row so that we know if we go over the size and need
// to adjust
for (var i=0; i < children.length; i++) {
if (i % dimensions.targetCols === 0) {
// This is a new row
row = {
children: [],
width: 0,
height: 0
};
rows.push(row);
}
var elem = children[i];
row.children.push(elem);
var targetWidth = dimensions.targetWidth;
var targetHeight = dimensions.targetHeight;
// If we're using a fixedRatio then we need to set the correct ratio for this element
if (fixedRatio) {
targetWidth = targetHeight / getVideoRatio(elem);
}
row.width += targetWidth;
row.height = targetHeight;
}
// Calculate total row height adjusting if we go too wide
var totalRowHeight = 0;
var remainingShortRows = 0;
for (i = 0; i < rows.length; i++) {
var row = rows[i];
if (row.width > Width) {
// Went over on the width, need to adjust the height proportionally
row.height = Math.floor(row.height * (Width / row.width));
row.width = Width;
} else if (row.width < Width) {
remainingShortRows += 1;
}
totalRowHeight += row.height;
}
if (totalRowHeight < Height && remainingShortRows > 0) {
// We can grow some of the rows, we're not taking up the whole height
var remainingHeightDiff = Height - totalRowHeight;
totalRowHeight = 0;
for (i = 0; i < rows.length; i++) {
var row = rows[i];
if (row.width < Width) {
// Evenly distribute the extra height between the short rows
var extraHeight = remainingHeightDiff / remainingShortRows;
if ((extraHeight / row.height) > ((Width - row.width) / row.width)) {
// We can't go that big or we'll go too wide
extraHeight = Math.floor(((Width - row.width) / row.width) * row.height);
}
row.width += Math.floor((extraHeight / row.height) * row.width);
row.height += extraHeight;
remainingHeightDiff -= extraHeight;
remainingShortRows -= 1;
}
totalRowHeight += row.height;
}
}
// vertical centering
y = ((Height - (totalRowHeight)) / 2);
// Iterate through each row and place each child
for (i = 0; i < rows.length; i++) {
var row = rows[i];
// center the row
var rowMarginLeft = ((Width - row.width) / 2);
x = rowMarginLeft;
for (var j = 0; j < row.children.length; j++) {
var elem = row.children[j];
var targetPosition = {
left: x + 'px',
top: y + 'px',
width: w + 'px',
height: h + 'px'
};
var targetWidth = dimensions.targetWidth;
var targetHeight = row.height;
// If we're using a fixedRatio then we need to set the correct ratio for this element
if (fixedRatio) {
targetWidth = Math.floor(targetHeight / getVideoRatio(elem));
}
css(elem, 'position', 'absolute');
var actualWidth = targetWidth - getCSSNumber(elem, 'paddingLeft') -
getCSSNumber(elem, 'paddingRight') -
getCSSNumber(elem, 'marginLeft') -
getCSSNumber(elem, 'marginRight') -
getCSSNumber(elem, 'borderLeft') -
getCSSNumber(elem, 'borderRight');
var fixAspectRatio = function fixAspectRatio() {
var sub = elem.querySelector('.OT_root');
if (sub) {
// If this is the parent of a subscriber or publisher then we need
// to force the mutation observer on the publisher or subscriber to
// trigger to get it to fix it's layout
var oldWidth = sub.style.width;
sub.style.width = w + 'px';
// sub.style.height = height + 'px';
sub.style.width = oldWidth || '';
}
};
var actualHeight = targetHeight - getCSSNumber(elem, 'paddingTop') -
getCSSNumber(elem, 'paddingBottom') -
getCSSNumber(elem, 'marginTop') -
getCSSNumber(elem, 'marginBottom') -
getCSSNumber(elem, 'borderTop') -
getCSSNumber(elem, 'borderBottom');
if (animate && $) {
$(elem).stop();
$(elem).animate(targetPosition, animate.duration || 200, animate.easing || 'swing', function () {
fixAspectRatio();
if (animate.complete) animate.complete.call(_this);
});
} else {
css(elem, targetPosition);
if (!elem.classList.contains('ot-layout')) {
elem.classList.add('ot-layout');
}
}
fixAspectRatio();
};
positionElement(elem, x+offsetLeft, y+offsetTop, actualWidth, actualHeight, animate);
x += targetWidth;
}
y += targetHeight;
}
};
var getVideoRatio = function getVideoRatio(elem) {
if (!elem) {
return 3 / 4;
}
var video = elem.querySelector('video');
if (video && video.videoHeight && video.videoWidth) {
return video.videoHeight / video.videoWidth;
}
if (elem.videoHeight && elem.videoWidth) {
return elem.videoHeight / elem.videoWidth;
}
return 3 / 4;
};
var filterDisplayNone = function (element) {
return css(element, 'display') !== 'none';
};
var getCSSNumber = function getCSSNumber(elem, prop) {
var cssStr = css(elem, prop);
return cssStr ? parseInt(cssStr, 10) : 0;
};
var layout = function layout(container, opts) {
if (css(container, 'display') === 'none') {
return;
}
var id = container.getAttribute('id');
if (!id) {
id = 'OT_' + cheapUUID();
container.setAttribute('id', id);
}
// Really cheap UUID function
var cheapUUID = function cheapUUID() {
return (Math.random() * 100000000).toFixed(0);
};
var Height = getHeight(container) -
getCSSNumber(container, 'borderTop') -
getCSSNumber(container, 'borderBottom'),
Width = getWidth(container) -
getCSSNumber(container, 'borderLeft') -
getCSSNumber(container, 'borderRight'),
availableRatio = Height/Width,
offsetLeft = 0,
offsetTop = 0,
bigOffsetTop = 0,
bigOffsetLeft = 0,
bigOnes = Array.prototype.filter.call(
container.querySelectorAll('#' + id + '>.' + opts.bigClass),
filterDisplayNone),
smallOnes = Array.prototype.filter.call(
container.querySelectorAll('#' + id + '>*:not(.' + opts.bigClass + ')'),
filterDisplayNone);
var getHeight = function getHeight(elem) {
var heightStr = height(elem);
return heightStr ? parseInt(heightStr, 10) : 0;
};
if (bigOnes.length > 0 && smallOnes.length > 0) {
var bigWidth, bigHeight;
var getWidth = function getWidth(elem) {
var widthStr = width(elem);
return widthStr ? parseInt(widthStr, 10) : 0;
};
if (availableRatio > getVideoRatio(bigOnes[0])) {
// We are tall, going to take up the whole width and arrange small
// guys at the bottom
bigWidth = Width;
bigHeight = Math.floor(Height * opts.bigPercentage);
offsetTop = bigHeight;
bigOffsetTop = Height - offsetTop;
} else {
// We are wide, going to take up the whole height and arrange the small
// guys on the right
bigHeight = Height;
bigWidth = Math.floor(Width * opts.bigPercentage);
offsetLeft = bigWidth;
bigOffsetLeft = Width - offsetLeft;
}
if (opts.bigFirst) {
arrange(bigOnes, bigWidth, bigHeight, 0, 0, opts.bigFixedRatio, opts.bigMinRatio,
opts.bigMaxRatio, opts.animate);
arrange(smallOnes, Width - offsetLeft, Height - offsetTop, offsetLeft, offsetTop,
opts.fixedRatio, opts.minRatio, opts.maxRatio, opts.animate);
} else {
arrange(smallOnes, Width - offsetLeft, Height - offsetTop, 0, 0, opts.fixedRatio,
opts.minRatio, opts.maxRatio, opts.animate);
arrange(bigOnes, bigWidth, bigHeight, bigOffsetLeft, bigOffsetTop,
opts.bigFixedRatio, opts.bigMinRatio, opts.bigMaxRatio, opts.animate);
}
} else if (bigOnes.length > 0 && smallOnes.length === 0) {
// We only have one bigOne just center it
arrange(bigOnes, Width, Height, 0, 0, opts.bigFixedRatio, opts.bigMinRatio,
opts.bigMaxRatio, opts.animate);
} else {
arrange(smallOnes, Width - offsetLeft, Height - offsetTop, offsetLeft, offsetTop,
opts.fixedRatio, opts.minRatio, opts.maxRatio, opts.animate);
}
};
var arrange = function arrange(children, containerWidth, containerHeight, offsetLeft, offsetTop, fixedRatio, minRatio, maxRatio, animate) {
var boxes = getLayout({
containerWidth: containerWidth,
containerHeight: containerHeight,
minRatio: minRatio,
maxRatio: maxRatio,
fixedRatio: fixedRatio
}, children.map(function (child) {
return getVideoRatio(child);
}));
var initLayoutContainer = function(container, opts) {
opts = defaults(opts || {}, {
maxRatio: 3/2,
minRatio: 9/16,
fixedRatio: false,
animate: false,
bigClass: 'OT_big',
bigPercentage: 0.8,
bigFixedRatio: false,
bigMaxRatio: 3/2,
bigMinRatio: 9/16,
bigFirst: true
});
container = typeof(container) === 'string' ? document.querySelector(container) : container;
boxes.forEach(function (box, idx) {
var elem = children[idx];
css(elem, 'position', 'absolute');
var actualWidth = box.width - getCSSNumber(elem, 'paddingLeft') - getCSSNumber(elem, 'paddingRight') - getCSSNumber(elem, 'marginLeft') - getCSSNumber(elem, 'marginRight') - getCSSNumber(elem, 'borderLeft') - getCSSNumber(elem, 'borderRight');
if (document.readyState === 'complete') {
layout(container, opts);
} else {
window.addEventListener('load', function() {
layout(container, opts);
});
}
var actualHeight = box.height - getCSSNumber(elem, 'paddingTop') - getCSSNumber(elem, 'paddingBottom') - getCSSNumber(elem, 'marginTop') - getCSSNumber(elem, 'marginBottom') - getCSSNumber(elem, 'borderTop') - getCSSNumber(elem, 'borderBottom');
return {
layout: layout.bind(null, container, opts)
};
};
positionElement(elem, box.left + offsetLeft, box.top + offsetTop, actualWidth, actualHeight, animate);
});
};
if (typeof module === 'undefined' || typeof module.exports === 'undefined') {
window.initLayoutContainer = initLayoutContainer;
module.exports = function (container, opts) {
var _opts$maxRatio = opts.maxRatio,
maxRatio = _opts$maxRatio === undefined ? 3 / 2 : _opts$maxRatio,
_opts$minRatio = opts.minRatio,
minRatio = _opts$minRatio === undefined ? 9 / 16 : _opts$minRatio,
_opts$fixedRatio = opts.fixedRatio,
fixedRatio = _opts$fixedRatio === undefined ? false : _opts$fixedRatio,
_opts$animate = opts.animate,
animate = _opts$animate === undefined ? false : _opts$animate,
_opts$bigClass = opts.bigClass,
bigClass = _opts$bigClass === undefined ? 'OT_big' : _opts$bigClass,
_opts$bigPercentage = opts.bigPercentage,
bigPercentage = _opts$bigPercentage === undefined ? 0.8 : _opts$bigPercentage,
_opts$bigFixedRatio = opts.bigFixedRatio,
bigFixedRatio = _opts$bigFixedRatio === undefined ? false : _opts$bigFixedRatio,
_opts$bigMaxRatio = opts.bigMaxRatio,
bigMaxRatio = _opts$bigMaxRatio === undefined ? 3 / 2 : _opts$bigMaxRatio,
_opts$bigMinRatio = opts.bigMinRatio,
bigMinRatio = _opts$bigMinRatio === undefined ? 9 / 16 : _opts$bigMinRatio,
_opts$bigFirst = opts.bigFirst,
bigFirst = _opts$bigFirst === undefined ? true : _opts$bigFirst;
var _opts$containerWidth = opts.containerWidth,
containerWidth = _opts$containerWidth === undefined ? 640 : _opts$containerWidth,
_opts$containerHeight = opts.containerHeight,
containerHeight = _opts$containerHeight === undefined ? 480 : _opts$containerHeight;
if (css(container, 'display') === 'none') {
return;
}
var id = container.getAttribute('id');
if (!id) {
id = 'OT_' + cheapUUID();
container.setAttribute('id', id);
}
containerHeight = getHeight(container) - getCSSNumber(container, 'borderTop') - getCSSNumber(container, 'borderBottom');
containerWidth = getWidth(container) - getCSSNumber(container, 'borderLeft') - getCSSNumber(container, 'borderRight');
var availableRatio = containerHeight / containerWidth;
var offsetLeft = 0;
var offsetTop = 0;
var bigOffsetTop = 0;
var bigOffsetLeft = 0;
var bigOnes = Array.prototype.filter.call(container.querySelectorAll('#' + id + '>.' + bigClass), filterDisplayNone);
var smallOnes = Array.prototype.filter.call(container.querySelectorAll('#' + id + '>*:not(.' + bigClass + ')'), filterDisplayNone);
if (bigOnes.length > 0 && smallOnes.length > 0) {
var bigWidth = void 0;
var bigHeight = void 0;
if (availableRatio > getVideoRatio(bigOnes[0])) {
// We are tall, going to take up the whole width and arrange small
// guys at the bottom
bigWidth = containerWidth;
bigHeight = Math.floor(containerHeight * bigPercentage);
offsetTop = bigHeight;
bigOffsetTop = containerHeight - offsetTop;
} else {
module.exports.initLayoutContainer = initLayoutContainer;
// We are wide, going to take up the whole height and arrange the small
// guys on the right
bigHeight = containerHeight;
bigWidth = Math.floor(containerWidth * bigPercentage);
offsetLeft = bigWidth;
bigOffsetLeft = containerWidth - offsetLeft;
}
if (bigFirst) {
arrange(bigOnes, bigWidth, bigHeight, 0, 0, bigFixedRatio, bigMinRatio, bigMaxRatio, animate);
arrange(smallOnes, containerWidth - offsetLeft, containerHeight - offsetTop, offsetLeft, offsetTop, fixedRatio, minRatio, maxRatio, animate);
} else {
arrange(smallOnes, containerWidth - offsetLeft, containerHeight - offsetTop, 0, 0, fixedRatio, minRatio, maxRatio, animate);
arrange(bigOnes, bigWidth, bigHeight, bigOffsetLeft, bigOffsetTop, bigFixedRatio, bigMinRatio, bigMaxRatio, animate);
}
} else if (bigOnes.length > 0 && smallOnes.length === 0) {
// We only have one bigOne just center it
arrange(bigOnes, containerWidth, containerHeight, 0, 0, bigFixedRatio, bigMinRatio, bigMaxRatio, animate);
} else {
arrange(smallOnes, containerWidth - offsetLeft, containerHeight - offsetTop, offsetLeft, offsetTop, fixedRatio, minRatio, maxRatio, animate);
}
};
})((typeof window !== 'undefined' && window.hasOwnProperty('jQuery')) ? window.jQuery : undefined);
/***/ })
/******/ ]);
});

@@ -0,1 +1,2 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.initLayoutContainer=e():t.initLayoutContainer=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function o(i){if(e[i])return e[i].exports;var r=e[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,o),r.l=!0,r.exports}return o.m=t,o.c=e,o.d=function(t,e,i){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)o.d(i,r,function(e){return t[e]}.bind(null,r));return i},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e,o){"use strict";
/*!

@@ -10,3 +11,3 @@ * opentok-layout-js (http://github.com/aullman/opentok-layout-js)

* @License: Released under the MIT license (http://opensource.org/licenses/MIT)
**/
!function(t){function i(t,e,o){if(o)t.style[e]=o;else{if("object"!=typeof e){var r=getComputedStyle(t),a=r.getPropertyValue(e);return""===a&&(a=t.style[e]),a}Object.keys(e).forEach(function(o){i(t,o,e[o])})}}function e(t){return t.offsetHeight>0?t.offsetHeight+"px":i(t,"height")}function o(t){return t.offsetWidth>0?t.offsetWidth+"px":i(t,"width")}function r(t,i){var e={};return Object.keys(i).forEach(function(o){t.hasOwnProperty(o)?e[o]=t[o]:e[o]=i[o]}),e}var a=function(e,o,r,a,n,d){var h={left:o+"px",top:r+"px",width:a+"px",height:n+"px"},g=function(){var t=e.querySelector(".OT_root");if(t){var i=t.style.width;t.style.width=a+"px",t.style.width=i||""}};d&&t?(t(e).stop(),t(e).animate(h,d.duration||200,d.easing||"swing",function(){g(),d.complete&&d.complete.call(this)})):(i(e,h),e.classList.contains("ot-layout")||e.classList.add("ot-layout")),g()},n=function(t){if(!t)return.75;var i=t.querySelector("video");return i&&i.videoHeight&&i.videoWidth?i.videoHeight/i.videoWidth:t.videoHeight&&t.videoWidth?t.videoHeight/t.videoWidth:.75},d=function(t,e){var o=i(t,e);return o?parseInt(o,10):0},h=function(){return(1e8*Math.random()).toFixed(0)},g=function(t){var i=e(t);return i?parseInt(i,10):0},l=function(t){var i=o(t);return i?parseInt(i,10):0},f=function(t,e,o,r,h,g,l,f,u){var s,c=t.length,p=function(t,i){for(var r,a,n,d,h,g,l,f,u=1;c>=u;u++){var s=u,p=Math.ceil(c/s);l=Math.floor(o/p),g=Math.floor(e/s),f=l/g,f>i?(f=i,l=g*f):t>f&&(f=t,g=l/f);var v=g*l*c;(void 0===r||v>r)&&(r=v,d=l,h=g,a=s,n=p)}return{maxArea:r,targetCols:a,targetRows:n,targetHeight:d,targetWidth:h,ratio:d/h}};if(g){var v=n(t.length>0?t[0]:null);s=p(v,v)}else s=p(l,f);for(var b,m=0,y=0,w=[],R=0;R<t.length;R++){R%s.targetCols===0&&(b={children:[],width:0,height:0},w.push(b));var x=t[R];b.children.push(x);var M=s.targetWidth,L=s.targetHeight;g&&(M=L/n(x)),b.width+=M,b.height=L}var W=0,C=0;for(R=0;R<w.length;R++){var b=w[R];b.width>e?(b.height=Math.floor(b.height*(e/b.width)),b.width=e):b.width<e&&(C+=1),W+=b.height}if(o>W&&C>0){var H=o-W;for(W=0,R=0;R<w.length;R++){var b=w[R];if(b.width<e){var A=H/C;A/b.height>(e-b.width)/b.width&&(A=Math.floor((e-b.width)/b.width*b.height)),b.width+=Math.floor(A/b.height*b.width),b.height+=A,H-=A,C-=1}W+=b.height}}for(y=(o-W)/2,R=0;R<w.length;R++){var b=w[R],F=(e-b.width)/2;m=F;for(var O=0;O<b.children.length;O++){var x=b.children[O],M=s.targetWidth,L=b.height;g&&(M=Math.floor(L/n(x))),i(x,"position","absolute");var S=M-d(x,"paddingLeft")-d(x,"paddingRight")-d(x,"marginLeft")-d(x,"marginRight")-d(x,"borderLeft")-d(x,"borderRight"),T=L-d(x,"paddingTop")-d(x,"paddingBottom")-d(x,"marginTop")-d(x,"marginBottom")-d(x,"borderTop")-d(x,"borderBottom");a(x,m+r,y+h,S,T,u),m+=M}y+=L}},u=function(t){return"none"!==i(t,"display")},s=function(t,e){if("none"!==i(t,"display")){var o=t.getAttribute("id");o||(o="OT_"+h(),t.setAttribute("id",o));var r=g(t)-d(t,"borderTop")-d(t,"borderBottom"),a=l(t)-d(t,"borderLeft")-d(t,"borderRight"),s=r/a,c=0,p=0,v=0,b=0,m=Array.prototype.filter.call(t.querySelectorAll("#"+o+">."+e.bigClass),u),y=Array.prototype.filter.call(t.querySelectorAll("#"+o+">*:not(."+e.bigClass+")"),u);if(m.length>0&&y.length>0){var w,R;s>n(m[0])?(w=a,R=Math.floor(r*e.bigPercentage),p=R,v=r-p):(R=r,w=Math.floor(a*e.bigPercentage),c=w,b=a-c),e.bigFirst?(f(m,w,R,0,0,e.bigFixedRatio,e.bigMinRatio,e.bigMaxRatio,e.animate),f(y,a-c,r-p,c,p,e.fixedRatio,e.minRatio,e.maxRatio,e.animate)):(f(y,a-c,r-p,0,0,e.fixedRatio,e.minRatio,e.maxRatio,e.animate),f(m,w,R,b,v,e.bigFixedRatio,e.bigMinRatio,e.bigMaxRatio,e.animate))}else m.length>0&&0===y.length?f(m,a,r,0,0,e.bigFixedRatio,e.bigMinRatio,e.bigMaxRatio,e.animate):f(y,a-c,r-p,c,p,e.fixedRatio,e.minRatio,e.maxRatio,e.animate)}},c=function(t,i){return i=r(i||{},{maxRatio:1.5,minRatio:9/16,fixedRatio:!1,animate:!1,bigClass:"OT_big",bigPercentage:.8,bigFixedRatio:!1,bigMaxRatio:1.5,bigMinRatio:9/16,bigFirst:!0}),t="string"==typeof t?document.querySelector(t):t,"complete"===document.readyState?s(t,i):window.addEventListener("load",function(){s(t,i)}),{layout:s.bind(null,t,i)}};"undefined"==typeof module||"undefined"==typeof module.exports?window.initLayoutContainer=c:module.exports.initLayoutContainer=c}("undefined"!=typeof window&&window.hasOwnProperty("jQuery")?window.jQuery:void 0);
* */var i=o(1),r=o(2);t.exports=function(t,e){return t="string"==typeof t?document.querySelector(t):t,"undefined"==typeof HTMLElement||t instanceof HTMLElement||e?e||(e={}):e=t,{layout:r.bind(this,t,e),getLayout:i.bind(this,e)}}},function(t,e,o){"use strict";var i=function(t,e,o,i,r){for(var n=void 0,a=void 0,d=void 0,f=void 0,u=void 0,h=void 0,l=void 0,c=void 0,v=1;v<=r;v+=1){var s=v,g=Math.ceil(r/s);(c=(l=Math.floor(i/g))/(h=Math.floor(o/s)))>e?l=h*(c=e):c<t&&(h=l/(c=t));var p=h*l*r;(void 0===n||p>n)&&(n=p,f=l,u=h,a=s,d=g)}return{maxArea:n,targetCols:a,targetRows:d,targetHeight:f,targetWidth:u,ratio:f/u}};t.exports=function(t,e){var o=t.maxRatio,r=void 0===o?1.5:o,n=t.minRatio,a=void 0===n?9/16:n,d=t.fixedRatio,f=void 0!==d&&d,u=t.containerWidth,h=void 0===u?640:u,l=t.containerHeight,c=void 0===l?480:l,v=e.length,s=void 0;if(f){var g=e.length>0?e[0]:null;s=i(g,g,h,c,v)}else s=i(a,r,h,c,v);for(var p=0,y=0,b=[],m=void 0,x=[],w=0;w<e.length;w+=1){w%s.targetCols==0&&(m={ratios:[],width:0,height:0},b.push(m));var M=e[w];m.ratios.push(M);var R=s.targetWidth,S=s.targetHeight;f&&(R=S/M),m.width+=R,m.height=S}for(var H=0,j=0,W=0;W<b.length;W+=1)(m=b[W]).width>h?(m.height=Math.floor(m.height*(h/m.width)),m.width=h):m.width<h&&(j+=1),H+=m.height;if(H<c&&j>0){var L=c-H;H=0;for(var O=0;O<b.length;O+=1){if((m=b[O]).width<h){var T=L/j;T/m.height>(h-m.width)/m.width&&(T=Math.floor((h-m.width)/m.width*m.height)),m.width+=Math.floor(T/m.height*m.width),m.height+=T,L-=T,j-=1}H+=m.height}}y=(c-H)/2;for(var _=0;_<b.length;_+=1){p=(h-(m=b[_]).width)/2;for(var A=void 0,P=0;P<m.ratios.length;P+=1){var C=m.ratios[P],q=s.targetWidth;A=m.height,f&&(q=Math.floor(A/C)),x.push({aspectRatio:C,left:p,top:y,width:q,height:A}),p+=q}y+=A}return x}},function(t,e,o){"use strict";var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=o(1);function n(t,e,o){if(o)return t.style[e]=o,NaN;if("object"===(void 0===e?"undefined":i(e)))return Object.keys(e).forEach(function(o){n(t,o,e[o])}),NaN;var r=getComputedStyle(t).getPropertyValue(e);return""===r&&(r=t.style[e]),r}var a=function(t){return"none"!==n(t,"display")};var d=function(t){if(!t)return.75;var e=t.querySelector("video");return e&&e.videoHeight&&e.videoWidth?e.videoHeight/e.videoWidth:t.videoHeight&&t.videoWidth?t.videoHeight/t.videoWidth:.75},f=function(t,e){var o=n(t,e);return o?parseInt(o,10):0},u=function(t){var e=function(t){return t.offsetHeight>0?t.offsetHeight+"px":n(t,"height")}(t);return e?parseInt(e,10):0},h=function(t){var e=function(t){return t.offsetWidth>0?t.offsetWidth+"px":n(t,"width")}(t);return e?parseInt(e,10):0},l=function(t,e,o,i,a,u,h,l,c){r({containerWidth:e,containerHeight:o,minRatio:h,maxRatio:l,fixedRatio:u},t.map(function(t){return d(t)})).forEach(function(e,o){var r=t[o];n(r,"position","absolute");var d=e.width-f(r,"paddingLeft")-f(r,"paddingRight")-f(r,"marginLeft")-f(r,"marginRight")-f(r,"borderLeft")-f(r,"borderRight"),u=e.height-f(r,"paddingTop")-f(r,"paddingBottom")-f(r,"marginTop")-f(r,"marginBottom")-f(r,"borderTop")-f(r,"borderBottom");!function(t,e,o,i,r,a){var d=this,f={left:e+"px",top:o+"px",width:i+"px",height:r+"px"},u=function(){var e=t.querySelector(".OT_root");if(e){var o=e.style.width;e.style.width=i+"px",e.style.width=o||""}};a&&$?($(t).stop(),$(t).animate(f,a.duration||200,a.easing||"swing",function(){u(),a.complete&&a.complete.call(d)})):(n(t,f),t.classList.contains("ot-layout")||t.classList.add("ot-layout")),u()}(r,e.left+i,e.top+a,d,u,c)})};t.exports=function(t,e){var o,i,r=e.maxRatio,c=void 0===r?1.5:r,v=e.minRatio,s=void 0===v?9/16:v,g=e.fixedRatio,p=void 0!==g&&g,y=e.animate,b=void 0!==y&&y,m=e.bigClass,x=void 0===m?"OT_big":m,w=e.bigPercentage,M=void 0===w?.8:w,R=e.bigFixedRatio,S=void 0!==R&&R,H=e.bigMaxRatio,j=void 0===H?1.5:H,W=e.bigMinRatio,L=void 0===W?9/16:W,O=e.bigFirst,T=void 0===O||O,_=e.containerWidth,A=e.containerHeight;if("none"!==n(t,"display")){var P=t.getAttribute("id");P||(P="OT_"+(1e8*Math.random()).toFixed(0),t.setAttribute("id",P));var C=(i=u(t)-f(t,"borderTop")-f(t,"borderBottom"))/(o=h(t)-f(t,"borderLeft")-f(t,"borderRight")),q=0,B=0,E=0,N=0,F=Array.prototype.filter.call(t.querySelectorAll("#"+P+">."+x),a),I=Array.prototype.filter.call(t.querySelectorAll("#"+P+">*:not(."+x+")"),a);if(F.length>0&&I.length>0){var $=void 0,k=void 0;C>d(F[0])?($=o,E=i-(B=k=Math.floor(i*M))):(k=i,N=o-(q=$=Math.floor(o*M))),T?(l(F,$,k,0,0,S,L,j,b),l(I,o-q,i-B,q,B,p,s,c,b)):(l(I,o-q,i-B,0,0,p,s,c,b),l(F,$,k,N,E,S,L,j,b))}else F.length>0&&0===I.length?l(F,o,i,0,0,S,L,j,b):l(I,o-q,i-B,q,B,p,s,c,b)}}}])});
//# sourceMappingURL=opentok-layout.min.js.map
{
"name": "opentok-layout-js",
"version": "2.1.0",
"version": "3.0.0",
"description": "Automatic layout of video elements (publisher and subscriber) minimising white-space for the OpenTok on WebRTC API. This is intended for use with the OpenTok on WebRTC JS API.",

@@ -8,7 +8,9 @@ "main": "opentok-layout.js",

"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"codeclimate-test-reporter": "0.0.4",
"gulp": "~3.5.5",
"gulp-jshint": "~1.5.0",
"gulp-rename": "~1.1.0",
"gulp-uglify": "~0.2.1",
"eslint": "^5.1.0",
"eslint-config-airbnb-base": "^13.0.0",
"eslint-plugin-import": "^2.13.0",
"http-server": "^0.8.0",

@@ -22,6 +24,9 @@ "karma": "^0.13.0",

"opentok-test-scripts": "^1.0.1",
"travis-multirunner": "^3.0.0"
"travis-multirunner": "^3.0.0",
"unminified-webpack-plugin": "^2.0.0",
"webpack": "^4.15.1",
"webpack-command": "^0.4.1"
},
"scripts": {
"test": "node ./tests/test-node.js && ./node_modules/.bin/run-tests",
"test": "npx eslint . && node ./tests/test-node.js && npx run-tests",
"start": "http-server"

@@ -28,0 +33,0 @@ },

@@ -43,5 +43,23 @@ [![Build Status](https://travis-ci.org/aullman/opentok-layout-js.svg?branch=master)](https://travis-ci.org/aullman/opentok-layout-js)

});
layout.layout()
layout.layout();
```
The other way to use this library is to just use the `getLayout()` method to get the layout and position the elements yourself. Get layout takes an array of aspect ratios (Height / Width) as the first argument.
```javascript
let boxes = layout.getLayout([480/640, 480/640, 720/1280]);
```
It will return an array of boxes which each have:
```javascript
{
width,
height,
aspectRatio,
top,
left
}
```
Examples

@@ -48,0 +66,0 @@ ----

// Karma configuration
// Generated on Wed Sep 03 2014 13:49:54 GMT+1000 (EST)
module.exports = function(config) {
var sauceLaunchers = {
'Ie': {
module.exports = (config) => {
const sauceLaunchers = {
Ie: {
base: 'SauceLabs',
browserName: 'internet explorer',
platform: process.env.BVER === '10' ? 'Windows 8' : 'Windows 8.1',
version: process.env.BVER
}
version: process.env.BVER,
},
};
var browser = process.env.BROWSER || 'chrome';
const browser = process.env.BROWSER || 'chrome';
config.set({

@@ -26,3 +26,3 @@

'../opentok-layout.js',
'**/*spec.js'
'**/*spec.js',
],

@@ -38,3 +38,3 @@

preprocessors: {
'opentok-layout.js': 'coverage'
'opentok-layout.js': 'coverage',
},

@@ -48,4 +48,4 @@

coverageReporter: {
type : 'lcov',
dir : '../coverage/'
type: 'lcov',
dir: '../coverage/',
},

@@ -57,3 +57,3 @@

startConnect: false,
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
},

@@ -81,4 +81,4 @@

// if true, Karma captures browsers, runs the tests and exits
singleRun: false
singleRun: false,
});
};

@@ -1,1 +0,3 @@

var layout = require('../opentok-layout.js');
const initLayoutContainer = require('../opentok-layout.js');
console.log(initLayoutContainer().getLayout([1.5, 1.5]));

@@ -1,23 +0,27 @@

/*globals describe, beforeEach, expect, it, afterEach, initLayoutContainer */
describe('opentok layout', function () {
it('defines initLayoutContainer', function () {
expect(window.hasOwnProperty('initLayoutContainer')).toBe(true);
/* globals describe, beforeEach, expect, it, afterEach, initLayoutContainer */
describe('opentok layout', () => {
it('defines initLayoutContainer', () => {
expect(typeof window.initLayoutContainer).toEqual('function');
});
it('defines a layout method', function () {
var layoutDiv = document.createElement('div');
it('defines layout and getLayout methods', () => {
const layoutDiv = document.createElement('div');
document.body.appendChild(layoutDiv);
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
expect(layoutContainer.hasOwnProperty('layout')).toBe(true);
expect(typeof layoutContainer.layout).toEqual('function');
expect(typeof layoutContainer.getLayout).toEqual('function');
});
it('does not break jQuery', function() {
it('does not break jQuery', () => {
expect(window.$).toBe(window.jQuery);
});
describe('handling layout of 2 elements', function () {
var layoutDiv, div1, div2;
beforeEach(function () {
describe('handling layout of 2 elements', () => {
let layoutDiv;
let div1;
let div2;
let expectedLayout;
let children;
beforeEach(() => {
layoutDiv = document.createElement('div');

@@ -41,5 +45,20 @@ layoutDiv.setAttribute('id', 'layoutDiv');

layoutDiv.appendChild(div2);
children = [div1, div2];
expectedLayout = [{
aspectRatio: 300 / 200,
width: 200,
height: 300,
left: 0,
top: 0,
},
{
aspectRatio: 300 / 200,
width: 200,
height: 300,
left: 200,
top: 0,
}];
});
afterEach(function () {
afterEach(() => {
document.body.removeChild(layoutDiv);

@@ -51,19 +70,24 @@ layoutDiv = null;

it('handles default layout', function () {
var layoutContainer = initLayoutContainer(layoutDiv);
it('handles default getLayout', () => {
const layoutContainer = initLayoutContainer({
containerWidth: 400,
containerHeight: 300,
});
expect(layoutContainer.getLayout(children.map(() => 300 / 200)))
.toEqual(expectedLayout);
});
it('handles default layout', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
expect(div1Rect.width).toBe(200);
expect(div2Rect.width).toBe(200);
expect(div1Rect.height).toBe(300);
expect(div2Rect.height).toBe(300);
expect(div1Rect.left).toBe(0);
expect(div1Rect.top).toBe(0);
expect(div2Rect.left).toBe(200);
expect(div2Rect.top).toBe(0);
expectedLayout.forEach((box, idx) => {
const boundingRect = children[idx].getBoundingClientRect();
['width', 'height', 'left', 'top'].forEach((val) => {
expect(boundingRect[val]).toEqual(expectedLayout[idx][val]);
});
});
});
it('adds the "ot-layout" class to elements', function() {
var layoutContainer = initLayoutContainer(layoutDiv);
it('adds the "ot-layout" class to elements', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();

@@ -74,3 +98,3 @@ expect(div1.classList.contains('ot-layout')).toBe(true);

it('maintains multiple aspect ratios if you set fixedRatio:true', function () {
it('maintains multiple aspect ratios if you set fixedRatio:true', () => {
div1.videoWidth = 640;

@@ -80,11 +104,11 @@ div1.videoHeight = 480;

div2.videoHeight = 640;
var layoutContainer = initLayoutContainer(layoutDiv, {fixedRatio: true});
const layoutContainer = initLayoutContainer(layoutDiv, { fixedRatio: true });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width/div1Rect.height).toBeCloseTo(640/480, 1);
var div2Rect = div2.getBoundingClientRect();
expect(div2Rect.width/div2Rect.height).toBeCloseTo(480/640, 1);
const div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width / div1Rect.height).toBeCloseTo(640 / 480, 1);
const div2Rect = div2.getBoundingClientRect();
expect(div2Rect.width / div2Rect.height).toBeCloseTo(480 / 640, 1);
});
it('grows to takes up the whole height if there are narrow elements', function() {
it('grows to takes up the whole height if there are narrow elements', () => {
// The second element is portrait and so it doesn't take up as much

@@ -97,6 +121,6 @@ // space as the first one. So we should account for that and make the height larger

layoutDiv.style.width = '660px';
var layoutContainer = initLayoutContainer(layoutDiv, {fixedRatio: true});
const layoutContainer = initLayoutContainer(layoutDiv, { fixedRatio: true });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
const div1Rect = div1.getBoundingClientRect();
const div2Rect = div2.getBoundingClientRect();
expect(div1Rect.height).toBe(300);

@@ -107,3 +131,3 @@ expect(div2Rect.height).toBe(300);

it('adjusts to not go over the width if you have a wider element', function() {
it('adjusts to not go over the width if you have a wider element', () => {
// The second element is 720p and so we need to adjust to not go over the width

@@ -115,25 +139,26 @@ div1.videoWidth = 640;

layoutDiv.style.width = '600px';
var layoutContainer = initLayoutContainer(layoutDiv, {fixedRatio: true});
const layoutContainer = initLayoutContainer(layoutDiv, { fixedRatio: true });
layoutContainer.layout();
var div2Rect = div2.getBoundingClientRect();
const div2Rect = div2.getBoundingClientRect();
expect(div2Rect.left + div2Rect.width).toBeLessThan(600);
});
it('lets you change the min and maxRatio to force a ratio', function () {
var layoutContainer = initLayoutContainer(layoutDiv, {minRatio: 9/16, maxRatio: 9/16});
it('lets you change the min and maxRatio to force a ratio', () => {
const layoutContainer = initLayoutContainer(layoutDiv,
{ minRatio: 9 / 16, maxRatio: 9 / 16 });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width/div1Rect.height).toBeCloseTo(16/9, 3);
const div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width / div1Rect.height).toBeCloseTo(16 / 9, 3);
});
describe('with a big element', function () {
beforeEach(function () {
describe('with a big element', () => {
beforeEach(() => {
div1.className = 'OT_big';
});
it('handles default layout', function () {
var layoutContainer = initLayoutContainer(layoutDiv);
it('handles default layout', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
const div1Rect = div1.getBoundingClientRect();
const div2Rect = div2.getBoundingClientRect();
expect(div1Rect.width).toBe(320);

@@ -149,22 +174,22 @@ expect(div2Rect.width).toBe(80);

it('handles bigFixedRatio:true', function () {
var layoutContainer = initLayoutContainer(layoutDiv, {bigFixedRatio: true});
it('handles bigFixedRatio:true', () => {
const layoutContainer = initLayoutContainer(layoutDiv, { bigFixedRatio: true });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width/div1Rect.height).toBeCloseTo(4/3, 3);
const div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width / div1Rect.height).toBeCloseTo(4 / 3, 3);
});
it('lets you change the bigMinRatio and bigMaxRatio to force a ratio', function () {
var layoutContainer =
initLayoutContainer(layoutDiv, {bigMinRatio: 9/16, bigMaxRatio: 9/16});
it('lets you change the bigMinRatio and bigMaxRatio to force a ratio', () => {
const layoutContainer = initLayoutContainer(layoutDiv,
{ bigMinRatio: 9 / 16, bigMaxRatio: 9 / 16 });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width/div1Rect.height).toBeCloseTo(16/9, 3);
const div1Rect = div1.getBoundingClientRect();
expect(div1Rect.width / div1Rect.height).toBeCloseTo(16 / 9, 3);
});
it('handles bigPercentage', function () {
var layoutContainer = initLayoutContainer(layoutDiv, {bigPercentage: 0.9});
it('handles bigPercentage', () => {
const layoutContainer = initLayoutContainer(layoutDiv, { bigPercentage: 0.9 });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
const div1Rect = div1.getBoundingClientRect();
const div2Rect = div2.getBoundingClientRect();
expect(div1Rect.width).toBe(360);

@@ -176,6 +201,6 @@ expect(div2Rect.width).toBe(40);

it('handles bigFirst', function () {
var layoutContainer = initLayoutContainer(layoutDiv, {bigFirst: false});
it('handles bigFirst', () => {
const layoutContainer = initLayoutContainer(layoutDiv, { bigFirst: false });
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
const div1Rect = div1.getBoundingClientRect();
expect(div1Rect.left).toBe(80);

@@ -185,10 +210,10 @@ expect(div1Rect.top).toBe(0);

it('takes margin into account', function () {
it('takes margin into account', () => {
div1.style.margin = '5px';
div2.style.margin = '5px';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
const div1Rect = div1.getBoundingClientRect();
const div2Rect = div2.getBoundingClientRect();
expect(div1Rect.width).toBe(310);

@@ -200,7 +225,7 @@ expect(div2Rect.width).toBe(70);

it('takes padding into account', function () {
it('takes padding into account', () => {
div1.style.padding = '5px';
div2.style.padding = '5px';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();

@@ -215,5 +240,6 @@ expect(div1.clientWidth).toBe(320);

describe('handling layout of 5 elements', function () {
var layoutDiv, divs = [], divCount = 5;
beforeEach(function () {
describe('handling layout of 5 elements', () => {
let layoutDiv; let divs = []; const
divCount = 5;
beforeEach(() => {
layoutDiv = document.createElement('div');

@@ -230,4 +256,4 @@ layoutDiv.setAttribute('id', 'layoutDiv');

document.body.appendChild(layoutDiv);
var colors = ['blue', 'green', 'orange', 'teal', 'yellow'];
for (var i = 0; i < divCount; i++) {
const colors = ['blue', 'green', 'orange', 'teal', 'yellow'];
for (let i = 0; i < divCount; i += 1) {
divs[i] = document.createElement('div');

@@ -239,3 +265,3 @@ divs[i].style.backgroundColor = colors[i];

afterEach(function () {
afterEach(() => {
document.body.removeChild(layoutDiv);

@@ -246,8 +272,8 @@ layoutDiv = null;

it('handles default layout', function () {
var layoutContainer = initLayoutContainer(layoutDiv);
it('handles default layout', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect them to all have the same width and height
var rect;
for (var i = 0; i < divs.length; i++) {
let rect;
for (let i = 0; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -274,3 +300,3 @@ expect(rect.width).toBe(133);

it('grows to takes up the whole height if there are narrow elements', function() {
it('grows to takes up the whole height if there are narrow elements', () => {
divs[1].videoWidth = 480;

@@ -282,14 +308,14 @@ divs[1].videoHeight = 640;

layoutDiv.style.height = '600px';
var layoutContainer = initLayoutContainer(layoutDiv, {fixedRatio: true});
const layoutContainer = initLayoutContainer(layoutDiv, { fixedRatio: true });
layoutContainer.layout();
var rect = divs[4].getBoundingClientRect();
const rect = divs[4].getBoundingClientRect();
expect(rect.top + rect.height).toBe(600);
});
it('handles a big element', function () {
it('handles a big element', () => {
divs[0].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBe(320);

@@ -300,4 +326,4 @@ expect(bigRect.height).toBe(300);

// Expect them to all have the same width and height
var rect;
for (var i = 1; i < divs.length; i++) {
let rect;
for (let i = 1; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -321,9 +347,9 @@ expect(rect.width).toBe(80);

it('handles two big elements', function () {
it('handles two big elements', () => {
divs[0].className = 'OT_big';
divs[1].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBeCloseTo(266.66, 1);

@@ -334,3 +360,3 @@ expect(bigRect.height).toBe(150);

// Expect div[1] to be big
var big2Rect = divs[1].getBoundingClientRect();
const big2Rect = divs[1].getBoundingClientRect();
expect(big2Rect.width).toBeCloseTo(266.66, 1);

@@ -341,4 +367,4 @@ expect(big2Rect.height).toBe(150);

// Expect them to all have the same width and height
var rect;
for (var i = 2; i < divs.length; i++) {
let rect;
for (let i = 2; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -359,8 +385,8 @@ expect(rect.width).toBe(80);

it('handles hidden elements', function () {
it('handles hidden elements', () => {
divs[0].style.display = 'none';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
for (var i = 1; i < divs.length; i++) {
var rect = divs[i].getBoundingClientRect();
for (let i = 1; i < divs.length; i += 1) {
const rect = divs[i].getBoundingClientRect();
expect(rect.width).toBe(200);

@@ -371,13 +397,13 @@ expect(rect.height).toBe(150);

describe('in really wide div', function () {
beforeEach(function () {
describe('in really wide div', () => {
beforeEach(() => {
layoutDiv.style.width = '1000px';
});
it('handles default layout', function () {
var layoutContainer = initLayoutContainer(layoutDiv);
it('handles default layout', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect them to all have the same width and height
var rect;
for (var i = 0; i < divs.length; i++) {
let rect;
for (let i = 0; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -404,8 +430,8 @@ expect(rect.width).toBe(200);

it('handles a big element', function () {
it('handles a big element', () => {
divs[0].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBeCloseTo(533.33, 1);

@@ -416,4 +442,4 @@ expect(bigRect.height).toBe(300);

// Expect them to all have the same width and height
var rect;
for (var i = 1; i < divs.length; i++) {
let rect;
for (let i = 1; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -437,9 +463,9 @@ expect(rect.width).toBe(100);

it('handles two big elements', function () {
it('handles two big elements', () => {
divs[0].className = 'OT_big';
divs[1].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBe(400);

@@ -450,3 +476,3 @@ expect(bigRect.height).toBe(300);

// Expect div[1] to be big
var big2Rect = divs[1].getBoundingClientRect();
const big2Rect = divs[1].getBoundingClientRect();
expect(big2Rect.width).toBe(400);

@@ -457,4 +483,4 @@ expect(big2Rect.height).toBe(300);

// Expect them to all have the same width and height
var rect;
for (var i = 2; i < divs.length; i++) {
let rect;
for (let i = 2; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -476,13 +502,13 @@ expect(rect.width).toBeCloseTo(177.76, 1);

describe('in really tall div', function () {
beforeEach(function () {
describe('in really tall div', () => {
beforeEach(() => {
layoutDiv.style.height = '800px';
});
it('handles default layout', function () {
var layoutContainer = initLayoutContainer(layoutDiv);
it('handles default layout', () => {
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect them to all have the same width and height
var rect;
for (var i = 0; i < divs.length; i++) {
let rect;
for (let i = 0; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -514,8 +540,8 @@ expect(rect.width).toBe(200);

it('handles a big element', function () {
it('handles a big element', () => {
divs[0].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBe(400);

@@ -526,4 +552,4 @@ expect(bigRect.height).toBe(600);

// Expect them to all have the same width and height
var rect;
for (var i = 1; i < divs.length; i++) {
let rect;
for (let i = 1; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -547,9 +573,9 @@ expect(rect.width).toBe(100);

it('handles two big elements', function () {
it('handles two big elements', () => {
divs[0].className = 'OT_big';
divs[1].className = 'OT_big';
var layoutContainer = initLayoutContainer(layoutDiv);
const layoutContainer = initLayoutContainer(layoutDiv);
layoutContainer.layout();
// Expect div[0] to be big
var bigRect = divs[0].getBoundingClientRect();
const bigRect = divs[0].getBoundingClientRect();
expect(bigRect.width).toBe(400);

@@ -560,3 +586,3 @@ expect(bigRect.height).toBe(320);

// Expect div[1] to be big
var big2Rect = divs[1].getBoundingClientRect();
const big2Rect = divs[1].getBoundingClientRect();
expect(big2Rect.width).toBe(400);

@@ -567,4 +593,4 @@ expect(big2Rect.height).toBe(320);

// Expect them to all have the same width and height
var rect;
for (var i = 2; i < divs.length; i++) {
let rect;
for (let i = 2; i < divs.length; i += 1) {
rect = divs[i].getBoundingClientRect();

@@ -571,0 +597,0 @@ expect(rect.width).toBe(133);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc