Skip to content

Commit b81c8a7

Browse files
committed
Use Resize/MutationObserver to detect detach/attach/resize
1 parent 7397a41 commit b81c8a7

File tree

16 files changed

+141
-423
lines changed

16 files changed

+141
-423
lines changed

docs/getting-started/integration.md

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,3 @@ require(['moment'], function() {
6464
});
6565
});
6666
```
67-
68-
## Content Security Policy
69-
70-
By default, Chart.js injects CSS directly into the DOM. For webpages secured using [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), this requires to allow `style-src 'unsafe-inline'`. For stricter CSP environments, where only `style-src 'self'` is allowed, the following CSS file needs to be manually added to your webpage:
71-
72-
```html
73-
<link rel="stylesheet" type="text/css" href="path/to/chartjs/dist/Chart.min.css">
74-
```
75-
76-
And the style injection must be turned off **before creating the first chart**:
77-
78-
```javascript
79-
// Disable automatic style injection
80-
Chart.platform.disableCSSInjection = true;
81-
```

docs/getting-started/v3-migration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Animation system was completely rewritten in Chart.js v3. Each property can now
8888
* `Chart.chart.chart`
8989
* `Chart.Controller`
9090
* `Chart.prototype.generateLegend`
91+
* `Chart.platform`
9192
* `Chart.types`
9293
* `Chart.Tooltip` is now provided by the tooltip plugin. The positioners can be accessed from `tooltipPlugin.positioners`
9394
* `DatasetController.addElementAndReset`
@@ -253,6 +254,6 @@ Animation system was completely rewritten in Chart.js v3. Each property can now
253254

254255
#### Platform
255256

256-
* `Chart.platform` is no longer the platform object used by charts. It contains only a single configuration option, `disableCSSInjection`. Every chart instance now has a separate platform instance.
257+
* `Chart.platform` is no longer the platform object used by charts. Every chart instance now has a separate platform instance.
257258
* `Chart.platforms` is an object that contains two usable platform classes, `BasicPlatform` and `DomPlatform`. It also contains `BasePlatform`, a class that all platforms must extend from.
258259
* If the canvas passed in is an instance of `OffscreenCanvas`, the `BasicPlatform` is automatically used.

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"merge-stream": "^1.0.1",
6767
"moment": "^2.10.2",
6868
"pixelmatch": "^5.0.0",
69+
"resize-observer-polyfill": "^1.5.1",
6970
"rollup": "^1.31.0",
7071
"rollup-plugin-babel": "^4.3.3",
7172
"rollup-plugin-cleanup": "^3.1.1",

rollup.config.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const babel = require('rollup-plugin-babel');
77
const cleanup = require('rollup-plugin-cleanup');
88
const terser = require('rollup-plugin-terser').terser;
99
const optional = require('./rollup.plugins').optional;
10-
const stylesheet = require('./rollup.plugins').stylesheet;
1110
const pkg = require('./package.json');
1211

1312
const input = 'src/index.js';
@@ -29,13 +28,12 @@ module.exports = [
2928
resolve(),
3029
commonjs(),
3130
babel(),
32-
stylesheet({
33-
extract: true
34-
}),
3531
optional({
3632
include: ['moment']
3733
}),
38-
cleanup(),
34+
cleanup({
35+
sourcemap: true
36+
})
3937
],
4038
output: {
4139
name: 'Chart',
@@ -60,10 +58,6 @@ module.exports = [
6058
optional({
6159
include: ['moment']
6260
}),
63-
stylesheet({
64-
extract: true,
65-
minify: true
66-
}),
6761
terser({
6862
output: {
6963
preamble: banner
@@ -93,10 +87,7 @@ module.exports = [
9387
resolve(),
9488
commonjs(),
9589
babel(),
96-
stylesheet({
97-
extract: true
98-
}),
99-
cleanup(),
90+
cleanup()
10091
],
10192
output: {
10293
name: 'Chart',
@@ -118,10 +109,6 @@ module.exports = [
118109
resolve(),
119110
commonjs(),
120111
babel(),
121-
stylesheet({
122-
extract: true,
123-
minify: true
124-
}),
125112
terser({
126113
output: {
127114
preamble: banner

samples/advanced/content-security-policy.css

Lines changed: 0 additions & 20 deletions
This file was deleted.

samples/advanced/content-security-policy.html

Lines changed: 0 additions & 27 deletions
This file was deleted.

samples/advanced/content-security-policy.js

Lines changed: 0 additions & 53 deletions
This file was deleted.

samples/samples.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,6 @@
244244
items: [{
245245
title: 'Progress bar',
246246
path: 'advanced/progress-bar.html'
247-
}, {
248-
title: 'Content Security Policy',
249-
path: 'advanced/content-security-policy.html'
250247
}, {
251248
title: 'Polar Area Radial Gradient',
252249
path: 'advanced/radial-gradient.html'

src/core/core.controller.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import layouts from './core.layouts';
77
import {BasicPlatform, DomPlatform} from '../platform/platforms';
88
import plugins from './core.plugins';
99
import scaleService from '../core/core.scaleService';
10+
import {getMaximumWidth, getMaximumHeight} from '../helpers/helpers.dom';
1011

1112
/**
1213
* @typedef { import("../platform/platform.base").IEvent } IEvent
@@ -246,15 +247,16 @@ class Chart {
246247
// Before init plugin notification
247248
plugins.notify(me, 'beforeInit');
248249

249-
helpers.dom.retinaScale(me, me.options.devicePixelRatio);
250-
251-
me.bindEvents();
250+
// helpers.dom.retinaScale(me, me.options.devicePixelRatio);
252251

253252
if (me.options.responsive) {
254-
// Initial resize before chart draws (must be silent to preserve initial animations).
255253
me.resize(true);
254+
} else {
255+
helpers.dom.retinaScale(me, me.options.devicePixelRatio);
256256
}
257257

258+
me.bindEvents();
259+
258260
// After init plugin notification
259261
plugins.notify(me, 'afterInit');
260262

@@ -285,19 +287,23 @@ class Chart {
285287
return this;
286288
}
287289

288-
resize(silent) {
290+
resize(silent, width, height) {
289291
const me = this;
290292
const options = me.options;
291293
const canvas = me.canvas;
292-
const aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
293-
const oldRatio = me.currentDevicePixelRatio;
294+
const aspectRatio = options.maintainAspectRatio && me.aspectRatio;
294295

296+
if (height === undefined) {
297+
width = getMaximumWidth(canvas);
298+
height = getMaximumHeight(canvas);
299+
}
295300
// the canvas render width and height will be casted to integers so make sure that
296301
// the canvas display style uses the same integer values to avoid blurring effect.
302+
const newWidth = Math.max(0, Math.floor(width));
303+
const newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : height));
297304

298-
// Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed
299-
const newWidth = Math.max(0, Math.floor(helpers.dom.getMaximumWidth(canvas)));
300-
const newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.dom.getMaximumHeight(canvas)));
305+
// detect devicePixelRation changes
306+
const oldRatio = me.currentDevicePixelRatio;
301307
const newRatio = options.devicePixelRatio || me.platform.getDevicePixelRatio();
302308

303309
if (me.width === newWidth && me.height === newHeight && oldRatio === newRatio) {
@@ -903,7 +909,7 @@ class Chart {
903909
if (canvas) {
904910
me.unbindEvents();
905911
helpers.canvas.clear(me);
906-
me.platform.releaseContext(me.ctx);
912+
me.platform.releaseContext(me, me.ctx);
907913
me.canvas = null;
908914
me.ctx = null;
909915
}
@@ -932,13 +938,11 @@ class Chart {
932938
listeners[type] = listener;
933939
});
934940

935-
// Elements used to detect size change should not be injected for non responsive charts.
936-
// See https://github.com/chartjs/Chart.js/issues/2210
937941
if (me.options.responsive) {
938-
listener = function() {
939-
me.resize();
942+
// resize
943+
listener = function(width, height) {
944+
me.resize(false, width, height);
940945
};
941-
942946
me.platform.addEventListener(me, 'resize', listener);
943947
listeners.resize = listener;
944948
}

0 commit comments

Comments
 (0)