/** @module stance/utils */ define('stance/utils',[ 'exports', 'core/utils/lang/isElement', 'core/utils/uniqueId', ], function ( exports, isElement, uniqueId ) { 'use strict'; /** * Extracts element from container if applicable. * * @param {Element-like} obj * @returns {?HTMLElement} */ exports.getElement = function (obj) { if (isElement(obj)) return obj; return obj && obj.el; }; exports.EL_ID_ATTR = 'data-visibility-id'; exports.OBJ_ID_PROP = '_visibility_id'; /** * Get or create an id for the element or element container, or return null. * * @param {Element-like} obj * @returns {?number} Id of the associated element / view */ exports.getId = function (obj) { // Gets the id (possibly creating it) var id = null; // TODO: Refactor if (isElement(obj)) { // Store the id as an element attribute id = obj.getAttribute(exports.EL_ID_ATTR) || null; if (!id) { id = uniqueId(); obj.setAttribute(exports.EL_ID_ATTR, id); } } else if (obj) { // Store it as a property id = obj[exports.OBJ_ID_PROP] || null; if (!id) id = obj[exports.OBJ_ID_PROP] = uniqueId(); } return id; }; /** * Calculate the the percentage of an element visible in * the viewport given the scroll position and the element's offset. * * @param {ViewportPos} pos - Scroll information. * @param {FullOffset} offset - Element's full offset information. * @returns {Integer} Percent between 0 and 100 */ exports.visiblePercent = function (pos, offset) { var percent = 0; if (!offset) return percent; var screenTop = pos.top; var screenBottom = screenTop + pos.height; var bleedsTop = offset.visibleTop < screenTop; var bleedsBottom = offset.visibleBottom > screenBottom; // If the view bleeds over the top and bottom of the viewport then it // is filling the entire viewport, so report 100%. Otherwise, if it // bleeds over neither, then it is completely in view, so also report 100%. if ((!bleedsTop && !bleedsBottom) || (bleedsTop && bleedsBottom)) percent = 1; // If the view is bleeding off the top, the calculate how much of the bottom of the view is visible. else if (bleedsTop) percent = (offset.height - (screenTop - offset.visibleTop)) / offset.height; // Otherwise, if bleeding off the bottom, then calculate how much of the top of the view is visible. else if (bleedsBottom) percent = (screenBottom - offset.visibleTop) / offset.height; return Math.round(percent * 100); }; }); // https://c.disquscdn.com/next/next-core/core/stance/utils.js