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;
|
||||
}
|
||||
|
||||
if (item instanceof HTMLCanvasElement) {
|
||||
// To prevent canvas fingerprinting, some add-ons undefine the getContext
|
||||
// method, for example: https://github.com/kkapsner/CanvasBlocker
|
||||
// https://github.com/chartjs/Chart.js/issues/2807
|
||||
var context = item.getContext && item.getContext('2d');
|
||||
if (context instanceof CanvasRenderingContext2D) {
|
||||
initCanvas(item, config);
|
||||
return context;
|
||||
}
|
||||
// To prevent canvas fingerprinting, some add-ons undefine the getContext
|
||||
// method, for example: https://github.com/kkapsner/CanvasBlocker
|
||||
// https://github.com/chartjs/Chart.js/issues/2807
|
||||
var context = item && item.getContext && item.getContext('2d');
|
||||
|
||||
// `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`.
|
||||
// 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;
|
||||
|
||||
@ -93,9 +93,9 @@ function toBeValidChart() {
|
||||
|
||||
if (!(actual instanceof 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';
|
||||
} 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';
|
||||
} else if (typeof actual.height !== 'number' || !isFinite(actual.height)) {
|
||||
message = 'Expected height to be a strict finite number';
|
||||
|
||||
@ -79,6 +79,28 @@ describe('Platform.dom', function() {
|
||||
|
||||
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() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user