mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Fix failing instanceof when reading context
`instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is inside an iframe or when running in a protected environment. We could guess the types from their toString() value but let's keep things flexible and assume it's a sufficient condition if the item has a context2D which has item as `canvas`.
This commit is contained in:
parent
f2c569ef25
commit
f7d2d7536a
@ -196,15 +196,21 @@ module.exports = function(Chart) {
|
|||||||
item = item.canvas;
|
item = item.canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item instanceof HTMLCanvasElement) {
|
// To prevent canvas fingerprinting, some add-ons undefine the getContext
|
||||||
// To prevent canvas fingerprinting, some add-ons undefine the getContext
|
// method, for example: https://github.com/kkapsner/CanvasBlocker
|
||||||
// method, for example: https://github.com/kkapsner/CanvasBlocker
|
// https://github.com/chartjs/Chart.js/issues/2807
|
||||||
// https://github.com/chartjs/Chart.js/issues/2807
|
var context = item && item.getContext && item.getContext('2d');
|
||||||
var context = item.getContext && item.getContext('2d');
|
|
||||||
if (context instanceof CanvasRenderingContext2D) {
|
// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
|
||||||
initCanvas(item, config);
|
// inside an iframe or when running in a protected environment. We could guess the
|
||||||
return context;
|
// types from their toString() value but let's keep things flexible and assume it's
|
||||||
}
|
// a sufficient condition if the item has a context2D which has item as `canvas`.
|
||||||
|
// https://github.com/chartjs/Chart.js/issues/3887
|
||||||
|
// https://github.com/chartjs/Chart.js/issues/4102
|
||||||
|
// https://github.com/chartjs/Chart.js/issues/4152
|
||||||
|
if (context && context.canvas === item) {
|
||||||
|
initCanvas(item, config);
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -93,9 +93,9 @@ function toBeValidChart() {
|
|||||||
|
|
||||||
if (!(actual instanceof Chart)) {
|
if (!(actual instanceof Chart)) {
|
||||||
message = 'Expected ' + actual + ' to be an instance of Chart';
|
message = 'Expected ' + actual + ' to be an instance of Chart';
|
||||||
} else if (!(actual.canvas instanceof HTMLCanvasElement)) {
|
} else if (Object.prototype.toString.call(actual.canvas) !== '[object HTMLCanvasElement]') {
|
||||||
message = 'Expected canvas to be an instance of HTMLCanvasElement';
|
message = 'Expected canvas to be an instance of HTMLCanvasElement';
|
||||||
} else if (!(actual.ctx instanceof CanvasRenderingContext2D)) {
|
} else if (Object.prototype.toString.call(actual.ctx) !== '[object CanvasRenderingContext2D]') {
|
||||||
message = 'Expected context to be an instance of CanvasRenderingContext2D';
|
message = 'Expected context to be an instance of CanvasRenderingContext2D';
|
||||||
} else if (typeof actual.height !== 'number' || !isFinite(actual.height)) {
|
} else if (typeof actual.height !== 'number' || !isFinite(actual.height)) {
|
||||||
message = 'Expected height to be a strict finite number';
|
message = 'Expected height to be a strict finite number';
|
||||||
|
|||||||
@ -79,6 +79,28 @@ describe('Platform.dom', function() {
|
|||||||
|
|
||||||
chart.destroy();
|
chart.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should accept a canvas from an iframe', function(done) {
|
||||||
|
var iframe = document.createElement('iframe');
|
||||||
|
iframe.onload = function() {
|
||||||
|
var doc = iframe.contentDocument;
|
||||||
|
doc.body.innerHTML += '<canvas id="chart"></canvas>';
|
||||||
|
var canvas = doc.getElementById('chart');
|
||||||
|
var chart = new Chart(canvas);
|
||||||
|
|
||||||
|
expect(chart).toBeValidChart();
|
||||||
|
expect(chart.canvas).toBe(canvas);
|
||||||
|
expect(chart.ctx).toBe(canvas.getContext('2d'));
|
||||||
|
|
||||||
|
chart.destroy();
|
||||||
|
canvas.remove();
|
||||||
|
iframe.remove();
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('config.options.aspectRatio', function() {
|
describe('config.options.aspectRatio', function() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user