Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorThomas Steur <thomas.steur@googlemail.com>2014-09-01 19:58:39 +0400
committerThomas Steur <thomas.steur@googlemail.com>2014-09-01 19:58:39 +0400
commit7d27436ab7b208549117e4d92746b39498e6eead (patch)
treed84e69a8dd6a1bc2bf11fdbf95fc4b3edf3ec811 /js
parente46fd0109ca16eb1e59e261bd9acb22bd104f392 (diff)
refs #4996 started to work on detecting whether an element is visible or not. This is quite a complex task and I do not think it can always work 100%. There are too many factors and ways to hide an element. For instance using a zIndex, zoom level, when a div is scrollable, CSS might not be applied yet at the time we scan etc. So far this should cover most cases but it must be clear it cannot work in all and there still needs to be a lot of testing. Also need to detect whether CSS was applied or not
Diffstat (limited to 'js')
-rw-r--r--js/piwik.js141
1 files changed, 140 insertions, 1 deletions
diff --git a/js/piwik.js b/js/piwik.js
index 82c670d175..0bdba3b1af 100644
--- a/js/piwik.js
+++ b/js/piwik.js
@@ -976,6 +976,127 @@ if (typeof Piwik !== 'object') {
}
/************************************************************
+ * Element Visiblility
+ ************************************************************/
+
+ /**
+ * Author: Jason Farrell
+ * Author URI: http://useallfive.com/
+ *
+ * Description: Checks if a DOM element is truly visible.
+ * Package URL: https://github.com/UseAllFive/true-visibility
+ * License: MIT (https://github.com/UseAllFive/true-visibility/blob/master/LICENSE.txt)
+ */
+ function isVisible (node) {
+
+ 'use strict';
+
+ /**
+ * Checks if a DOM element is visible. Takes into
+ * consideration its parents and overflow.
+ *
+ * @param (el) the DOM element to check if is visible
+ *
+ * These params are optional that are sent in recursively,
+ * you typically won't use these:
+ *
+ * @param (t) Top corner position number
+ * @param (r) Right corner position number
+ * @param (b) Bottom corner position number
+ * @param (l) Left corner position number
+ * @param (w) Element width number
+ * @param (h) Element height number
+ */
+ function _isVisible(el, t, r, b, l, w, h) {
+ var p = el.parentNode,
+ VISIBLE_PADDING = 2;
+
+ if ( !_elementInDocument(el) ) {
+ return false;
+ }
+
+ //-- Return true for document node
+ if ( 9 === p.nodeType ) {
+ return true;
+ }
+
+ //-- Return false if our element is invisible
+ if (
+ '0' === _getStyle(el, 'opacity') ||
+ 'none' === _getStyle(el, 'display') ||
+ 'hidden' === _getStyle(el, 'visibility')
+ ) {
+ return false;
+ }
+
+ if (
+ 'undefined' === typeof(t) ||
+ 'undefined' === typeof(r) ||
+ 'undefined' === typeof(b) ||
+ 'undefined' === typeof(l) ||
+ 'undefined' === typeof(w) ||
+ 'undefined' === typeof(h)
+ ) {
+ t = el.offsetTop;
+ l = el.offsetLeft;
+ b = t + el.offsetHeight;
+ r = l + el.offsetWidth;
+ w = el.offsetWidth;
+ h = el.offsetHeight;
+ }
+ //-- If we have a parent, let's continue:
+ if ( p ) {
+ //-- Check if the parent can hide its children.
+ if ( ('hidden' === _getStyle(p, 'overflow') || 'scroll' === _getStyle(p, 'overflow')) ) {
+ //-- Only check if the offset is different for the parent
+ if (
+ //-- If the target element is to the right of the parent elm
+ l + VISIBLE_PADDING > p.offsetWidth + p.scrollLeft ||
+ //-- If the target element is to the left of the parent elm
+ l + w - VISIBLE_PADDING < p.scrollLeft ||
+ //-- If the target element is under the parent elm
+ t + VISIBLE_PADDING > p.offsetHeight + p.scrollTop ||
+ //-- If the target element is above the parent elm
+ t + h - VISIBLE_PADDING < p.scrollTop
+ ) {
+ //-- Our target element is out of bounds:
+ return false;
+ }
+ }
+ //-- Add the offset parent's left/top coords to our element's offset:
+ if ( el.offsetParent === p ) {
+ l += p.offsetLeft;
+ t += p.offsetTop;
+ }
+ //-- Let's recursively check upwards:
+ return _isVisible(p, t, r, b, l, w, h);
+ }
+ return true;
+ }
+
+ //-- Cross browser method to get style properties:
+ function _getStyle(el, property) {
+ if ( window.getComputedStyle ) {
+ return document.defaultView.getComputedStyle(el,null)[property];
+ }
+ if ( el.currentStyle ) {
+ return el.currentStyle[property];
+ }
+ }
+
+ function _elementInDocument(element) {
+ while (element = element.parentNode) {
+ if (element == document) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return _isVisible(node);
+ };
+
+ /************************************************************
* Query
************************************************************/
@@ -1383,7 +1504,6 @@ if (typeof Piwik !== 'object') {
return query.getAttributeValueFromNode(node, 'data');
}
-
},
trim: function (text) {
if (text && (''+text) === text) {
@@ -1392,6 +1512,25 @@ if (typeof Piwik !== 'object') {
return text;
},
+ isNodeInViewport: function (node) {
+
+ if (!node || !node.getBoundingClientRect || node.nodeType !== 1) {
+ return true;
+ }
+
+ var rect = node.getBoundingClientRect();
+ var html = document.documentElement ? document.documentElement : {};
+
+ return (
+ rect.bottom > 0 &&
+ rect.right > 0 &&
+ rect.left < (window.innerWidth || html.clientWidth) &&
+ rect.top < (window.innerHeight || html.clientHeight)
+ );
+ },
+ isNodeVisible: function (node) {
+ return isVisible(node) && this.isNodeInViewport(node);
+ },
buildInteractionRequestParams: function (name, piece, interaction)
{
return 'c_n=' + encodeWrapper(name) +