]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Replace the IFRAME resizer by DIVs (#4596)
authorSimon Brunel <simonbrunel@users.noreply.github.com>
Wed, 2 Aug 2017 05:25:55 +0000 (07:25 +0200)
committerGitHub <noreply@github.com>
Wed, 2 Aug 2017 05:25:55 +0000 (07:25 +0200)
Resize detection is now based on scroll events from two divs nested under a main one. Implementation inspired from https://github.com/marcj/css-element-queries.

src/core/core.controller.js
src/platforms/platform.dom.js
test/specs/core.controller.tests.js

index 1dbf90f0162d11c3797310c9ff5d212c0c6cbe8a..5ae591d41fee059e6b40d0f4e37b420882463011 100644 (file)
@@ -731,9 +731,7 @@ module.exports = function(Chart) {
                                listeners[type] = listener;
                        });
 
-                       // Responsiveness is currently based on the use of an iframe, however this method causes
-                       // performance issues and could be troublesome when used with ad blockers. So make sure
-                       // that the user is still able to create a chart without iframe when responsive is false.
+                       // Elements used to detect size change should not be injected for non responsive charts.
                        // See https://github.com/chartjs/Chart.js/issues/2210
                        if (me.options.responsive) {
                                listener = function() {
index 2659ac6a43326de892ebfcec70c47625a30c0aa7..8fe9f27073c58bf00665ba00f283af2d10c894bb 100644 (file)
@@ -165,43 +165,62 @@ function throttled(fn, thisArg) {
        };
 }
 
+// Implementation based on https://github.com/marcj/css-element-queries
 function createResizer(handler) {
-       var iframe = document.createElement('iframe');
-       iframe.className = 'chartjs-hidden-iframe';
-       iframe.style.cssText =
-               'display:block;' +
-               'overflow:hidden;' +
-               'border:0;' +
-               'margin:0;' +
-               'top:0;' +
+       var resizer = document.createElement('div');
+       var cls = CSS_PREFIX + 'size-monitor';
+       var maxSize = 1000000;
+       var style =
+               'position:absolute;' +
                'left:0;' +
-               'bottom:0;' +
+               'top:0;' +
                'right:0;' +
-               'height:100%;' +
-               'width:100%;' +
-               'position:absolute;' +
+               'bottom:0;' +
+               'overflow:hidden;' +
                'pointer-events:none;' +
+               'visibility:hidden;' +
                'z-index:-1;';
 
-       // Prevent the iframe to gain focus on tab.
-       // https://github.com/chartjs/Chart.js/issues/3090
-       iframe.tabIndex = -1;
-
-       // Prevent iframe from gaining focus on ItemMode keyboard navigation
-       // Accessibility bug fix
-       iframe.setAttribute('aria-hidden', 'true');
-
-       // If the iframe is re-attached to the DOM, the resize listener is removed because the
-       // content is reloaded, so make sure to install the handler after the iframe is loaded.
-       // https://github.com/chartjs/Chart.js/issues/3521
-       addEventListener(iframe, 'load', function() {
-               addEventListener(iframe.contentWindow || iframe, 'resize', handler);
-               // The iframe size might have changed while loading, which can also
-               // happen if the size has been changed while detached from the DOM.
+       resizer.style.cssText = style;
+       resizer.className = cls;
+       resizer.innerHTML =
+               '<div class="' + cls + '-expand" style="' + style + '">' +
+                       '<div style="' +
+                               'position:absolute;' +
+                               'width:' + maxSize + 'px;' +
+                               'height:' + maxSize + 'px;' +
+                               'left:0;' +
+                               'top:0">' +
+                       '</div>' +
+               '</div>' +
+               '<div class="' + cls + '-shrink" style="' + style + '">' +
+                       '<div style="' +
+                               'position:absolute;' +
+                               'width:200%;' +
+                               'height:200%;' +
+                               'left:0; ' +
+                               'top:0">' +
+                       '</div>' +
+               '</div>';
+
+       var expand = resizer.childNodes[0];
+       var shrink = resizer.childNodes[1];
+
+       resizer._reset = function() {
+               expand.scrollLeft = maxSize;
+               expand.scrollTop = maxSize;
+               shrink.scrollLeft = maxSize;
+               shrink.scrollTop = maxSize;
+       };
+       var onScroll = function() {
+               resizer._reset();
                handler();
-       });
+       };
+
+       addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand'));
+       addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));
 
-       return iframe;
+       return resizer;
 }
 
 // https://davidwalsh.name/detect-node-insertion
@@ -253,6 +272,9 @@ function addResizeListener(node, listener, chart) {
                        if (container && container !== resizer.parentNode) {
                                container.insertBefore(resizer, container.firstChild);
                        }
+
+                       // The container size might have changed, let's reset the resizer state.
+                       resizer._reset();
                }
        });
 }
index 24f062b78d3abc2625072a5517640c6adc6b785e..76740315ae172f16522edb1cc4a3ff2774253199 100644 (file)
@@ -420,7 +420,8 @@ describe('Chart', function() {
 
                        waitForResize(chart, function() {
                                var resizer = wrapper.firstChild;
-                               expect(resizer.tagName).toBe('IFRAME');
+                               expect(resizer.className).toBe('chartjs-size-monitor');
+                               expect(resizer.tagName).toBe('DIV');
                                expect(chart).toBeChartOfSize({
                                        dw: 455, dh: 355,
                                        rw: 455, rh: 355,
@@ -687,7 +688,8 @@ describe('Chart', function() {
                                var wrapper = chart.canvas.parentNode;
                                var resizer = wrapper.firstChild;
                                expect(wrapper.childNodes.length).toBe(2);
-                               expect(resizer.tagName).toBe('IFRAME');
+                               expect(resizer.className).toBe('chartjs-size-monitor');
+                               expect(resizer.tagName).toBe('DIV');
 
                                chart.destroy();