Skip to content

Commit

Permalink
- Merge branch 'iframe-sandbox-support' of github.com:plotly/dash int…
Browse files Browse the repository at this point in the history
…o iframe-sandbox-support

- Update build artifacts

# Conflicts:
#	dash-renderer/src/AccessDenied.react.js
#	dash-renderer/src/actions/index.js
#	tests/integration/renderer/test_iframe.py
  • Loading branch information
Marc-André Rivet committed Feb 4, 2020
2 parents c2d6dce + 8ee3588 commit a3a7859
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 22 deletions.
2 changes: 1 addition & 1 deletion @plotly/dash-component-plugins/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@plotly/dash-component-plugins",
"version": "1.0.2",
"version": "1.2.0",
"description": "Plugins for Dash Components",
"repository": {
"type": "git",
Expand Down
13 changes: 13 additions & 0 deletions @plotly/dash-component-plugins/src/History.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const ON_CHANGE = '_dashprivate_historychange';

export default class History {
static dispatchChangeEvent() {
window.dispatchEvent(new CustomEvent(ON_CHANGE));
}

static onChange(listener) {
window.addEventListener(ON_CHANGE, listener);

return () => window.removeEventListener(ON_CHANGE, listener);
}
}
6 changes: 6 additions & 0 deletions @plotly/dash-component-plugins/src/dynamicImport.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,11 @@ export const asyncDecorator = (target, promise) => {
return state.get;
};

export const inheritAsyncDecorator = (target, source) => {
Object.defineProperty(target, '_dashprivate_isLazyComponentReady', {
get: () => isReady(source)
});
}

export const isReady = target => target &&
target._dashprivate_isLazyComponentReady;
6 changes: 4 additions & 2 deletions @plotly/dash-component-plugins/src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { asyncDecorator, isReady } from './dynamicImport';
import { asyncDecorator, inheritAsyncDecorator, isReady } from './dynamicImport';
import History from './History';

export { asyncDecorator, isReady };
export { asyncDecorator, inheritAsyncDecorator, isReady };
export { History };
2 changes: 1 addition & 1 deletion @plotly/webpack-dash-dynamic-import/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@plotly/webpack-dash-dynamic-import",
"version": "1.1.4",
"version": "1.1.5",
"description": "Webpack Plugin for Dynamic Import in Dash",
"repository": {
"type": "git",
Expand Down
10 changes: 9 additions & 1 deletion @plotly/webpack-dash-dynamic-import/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ var getCurrentScript = function() {
if (!script) {
/* Shim for IE11 and below */
/* Do not take into account async scripts and inline scripts */
var scripts = Array.from(document.getElementsByTagName('script')).filter(function(s) { return !s.async && !s.text && !s.textContent; });
var doc_scripts = document.getElementsByTagName('script');
var scripts = [];
for (var i = 0; i < doc_scripts.length; i++) {
scripts.push(doc_scripts[i]);
}
scripts = scripts.filter(function(s) { return !s.async && !s.text && !s.textContent; });
script = scripts.slice(-1)[0];
}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to `dash` will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [1.9.0] - 2020-02-04
### Fixed
- [#1080](https://github.com/plotly/dash/pull/1080) Handle case where dash fails to load when used inside an iframe with a sandbox attribute that only has allow-scripts

## [1.8.0] - 2020-01-14
### Added
- [#1073](https://github.com/plotly/dash/pull/1073) Two new functions to simplify usage handling URLs and pathnames: `app.get_relative_path` & `app.trim_relative_path`.
Expand Down
14 changes: 11 additions & 3 deletions dash-renderer/dash_renderer/dash_renderer.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -30344,10 +30344,18 @@ function hydrateInitialOutputs() {
dispatch(setAppLifecycle(Object(_reducers_constants__WEBPACK_IMPORTED_MODULE_3__["getAppState"])('HYDRATED')));
};
}
/* eslint-disable-next-line no-console */

var logWarningOnce = Object(ramda__WEBPACK_IMPORTED_MODULE_0__["once"])(console.warn);
function getCSRFHeader() {
return {
'X-CSRFToken': cookie__WEBPACK_IMPORTED_MODULE_5___default.a.parse(document.cookie)._csrf_token
};
try {
return {
'X-CSRFToken': cookie__WEBPACK_IMPORTED_MODULE_5___default.a.parse(document.cookie)._csrf_token
};
} catch (e) {
logWarningOnce(e);
return {};
}
}

function triggerDefaultState(dispatch, getState) {
Expand Down
2 changes: 1 addition & 1 deletion dash-renderer/dash_renderer/dash_renderer.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dash-renderer/digest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"MD5 (dash_renderer.dev.js)":"561787639c4e4e6dfc2ed334f8b9c08e",
"MD5 (dash_renderer.min.js)":"b89f7fc48aecc81250a3a002f0f0a5a0",
"MD5 (dash_renderer.dev.js)":"cf7796e1ced87563812cea38d16ea281",
"MD5 (dash_renderer.min.js)":"c6e5cda1b2572fee63e19b344258b512",
"MD5 (polyfill@7.7.0.min.js)":"ed6472b73ae010eee88282933a04c2a1",
"MD5 (prop-types@15.7.2.js)":"85947944e396a28895fad5f553eee36f",
"MD5 (prop-types@15.7.2.min.js)":"e3053393609bd2744010498629a43597",
Expand Down
2 changes: 1 addition & 1 deletion dash-renderer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-renderer",
"version": "1.2.3",
"version": "1.2.4",
"description": "render dash components in react",
"main": "dash_renderer/dash_renderer.min.js",
"scripts": {
Expand Down
16 changes: 12 additions & 4 deletions dash-renderer/src/AccessDenied.react.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/* global window:true, document:true */
import React from 'react';
import {mergeRight} from 'ramda';
import {mergeRight, once} from 'ramda';
import PropTypes from 'prop-types';
import * as styles from './styles/styles.js';
import * as constants from './constants/constants.js';

/* eslint-disable-next-line no-console */
const logWarningOnce = once(console.warn);

function AccessDenied(props) {
const {config} = props;
const fid = config.fid;
Expand All @@ -28,9 +31,14 @@ function AccessDenied(props) {
<a
style={styles.base.a}
onClick={() => {
document.cookie =
`${constants.OAUTH_COOKIE_NAME}=; ` +
'expires=Thu, 01 Jan 1970 00:00:01 GMT;';
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
try {
document.cookie =
`${constants.OAUTH_COOKIE_NAME}=; ` +
'expires=Thu, 01 Jan 1970 00:00:01 GMT;';
} catch (e) {
logWarningOnce(e);
}
window.location.reload(true);
}}
>
Expand Down
15 changes: 12 additions & 3 deletions dash-renderer/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
lensPath,
mergeLeft,
mergeDeepRight,
once,
path,
pluck,
propEq,
Expand Down Expand Up @@ -54,10 +55,18 @@ export function hydrateInitialOutputs() {
};
}

/* eslint-disable-next-line no-console */
const logWarningOnce = once(console.warn);

export function getCSRFHeader() {
return {
'X-CSRFToken': cookie.parse(document.cookie)._csrf_token,
};
try {
return {
'X-CSRFToken': cookie.parse(document.cookie)._csrf_token,
};
} catch (e) {
logWarningOnce(e);
return {};
}
}

function triggerDefaultState(dispatch, getState) {
Expand Down
2 changes: 1 addition & 1 deletion dash/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.8.0'
__version__ = '1.9.0'
4 changes: 2 additions & 2 deletions requires-install.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Flask>=1.0.2
flask-compress
plotly
dash_renderer==1.2.3
dash-core-components==1.7.0
dash_renderer==1.2.4
dash-core-components==1.8.0
dash-html-components==1.0.2
dash-table==4.6.0
future
57 changes: 57 additions & 0 deletions tests/integration/renderer/test_iframe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from multiprocessing import Value

import dash
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate

import dash_html_components as html


def test_rdif001_sandbox_allow_scripts(dash_duo):
app = dash.Dash(__name__)
call_count = Value("i")

N_OUTPUTS = 50

app.layout = html.Div([
html.Button("click me", id="btn"),
] + [html.Div(id="output-{}".format(i)) for i in range(N_OUTPUTS)])

@app.callback(
[Output("output-{}".format(i), "children") for i in range(N_OUTPUTS)],
[Input("btn", "n_clicks")]
)
def update_output(n_clicks):
if n_clicks is None:
raise PreventUpdate

call_count.value += 1
return ["{}={}".format(i, i + n_clicks) for i in range(N_OUTPUTS)]

@app.server.after_request
def apply_cors(response):
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization"
return response

dash_duo.start_server(app)

iframe = """
<!DOCTYPE html>
<html>
<iframe src="{0}" sandbox="allow-scripts">
</iframe>
</html>
"""

html_content = iframe.format(dash_duo.server_url)

dash_duo.driver.get("data:text/html;charset=utf-8," + html_content)

dash_duo.driver.switch_to.frame(0)

dash_duo.wait_for_element('#output-0')
dash_duo.wait_for_element_by_id('btn').click()
dash_duo.wait_for_element('#output-0').text == '0=1'

assert len(dash_duo.get_logs()) != 0

0 comments on commit a3a7859

Please sign in to comment.