Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

Document discouraged elements, and fix ObjectEl data #178

Merged
merged 7 commits into from
Jan 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
version: 2

jobs:
percy-finalize:
docker:
- image: percyio/agent
auth:
username: dashautomation
password: $DASH_PAT_DOCKERHUB
steps:
- run: percy finalize --all

python-2.7: &test-template
docker:
- image: circleci/python:2.7-stretch-node-browsers
Expand All @@ -9,7 +18,7 @@ jobs:
password: $DASH_PAT_DOCKERHUB
environment:
PYTHON_VERSION: py27
PERCY_ENABLE: 1
PERCY_ENABLE: 0

working_directory: ~/repo

Expand Down Expand Up @@ -76,7 +85,8 @@ jobs:
password: $DASH_PAT_DOCKERHUB
environment:
PYTHON_VERSION: py37
PERCY_ENABLE: 0
PERCY_ENABLE: 1
PERCY_PARALLEL_TOTAL: -1

workflows:
version: 2
Expand All @@ -85,3 +95,6 @@ workflows:
- python-2.7
- python-3.6
- python-3.7
- percy-finalize:
requires:
- python-3.7
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 this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## UNRELEASED
### Fixed
- [#178](https://github.com/plotly/dash-html-components/pull/178) - Fix [#161](https://github.com/plotly/dash-html-components/issues/161) <object> `data` property, and fix [#129](https://github.com/plotly/dash-html-components/issues/129) obsolete, deprecated, and discouraged elements. No elements were removed, but comments were added to the documentation about these elements detailing their limitations.

## [1.1.2] - 2021-01-19
### Fixed
- [#169](https://github.com/plotly/dash-html-components/pull/169) - part of fixing dash import bug https://github.com/plotly/dash/issues/1143
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"postbuild": "es-check es5 dash_html_components/*.js",
"build:watch": "watch 'npm run build' src",
"test:import": "python -m unittest tests.test_dash_import",
"test:py": "python -m unittest tests.test_dash_html_components tests.test_integration",
"test:py": "pytest --nopercyfinalize --headless tests/test_dash_html_components.py tests/test_integration.py",
"test": "run-s -c test:py test:import lint"
},
"author": "Chris Parmer <[email protected]>",
Expand Down
7 changes: 3 additions & 4 deletions scripts/extract-attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ const dataPath = './data/attributes.json';
const htmlPath = './data/attributes.html';

// From https://facebook.github.io/react/docs/tags-and-attributes.html#supported-attributes
// less the `data` attribute,
// the special `className` and `htmlFor` props,
// less the special `className` and `htmlFor` props,
// and `httpEquiv` + `acceptCharset` which are already correctly camelCased.
const supportedAttributes = ['accept', 'accessKey', 'action',
'allowFullScreen', 'allowTransparency', 'alt', 'async', 'autoComplete',
'autoFocus', 'autoPlay', 'capture', 'cellPadding', 'cellSpacing', 'challenge',
'charSet', 'checked', 'cite', 'classID', 'colSpan', 'cols', 'content',
'contentEditable', 'contextMenu', 'controls', 'coords', 'crossOrigin',
'contentEditable', 'contextMenu', 'controls', 'coords', 'crossOrigin', 'data',
'dateTime', 'default', 'defer', 'dir', 'disabled', 'download', 'draggable',
'encType', 'form', 'formAction', 'formEncType', 'formMethod', 'formNoValidate',
'formTarget', 'frameBorder', 'headers', 'height', 'hidden', 'high', 'href',
Expand Down Expand Up @@ -82,7 +81,7 @@ function extractAttributes($) {
.toString();

// Skip `data-*` attributes
if (htmlAttribute.indexOf('data') === 0) {
if (htmlAttribute.indexOf('data-') === 0) {
return;
}

Expand Down
10 changes: 9 additions & 1 deletion scripts/extract-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ function extractElements($) {
'svg', 'math',
// obsolete, non-standard, or deprecated tags
'image', 'dir', 'tt', 'applet', 'noembed', 'bgsound', 'menu', 'menuitem',
'noframes'
'noframes',
// experimental, don't add yet
'portal'
];
// `<section>` is for some reason missing from the reference tables.
// `<command>` and `element` are obsolete and has been removed from the
// reference table, but we had them in the past so we should wait for a
// major to remove
const addElements = [
'base',
'command',
'element',
'section',
'h1',
'h2',
Expand Down Expand Up @@ -64,6 +71,7 @@ request(refUrl, (error, response, html) => {
if (elements.length !== expectedElCount) {
throw new Error(
'Unexpected number of elements extracted from ' + refUrl +
' - Found ' + elements.length + ' but expected ' + expectedElCount +
' Check the output and edit expectedElCount if this is intended.'
);
}
Expand Down
54 changes: 53 additions & 1 deletion scripts/generate-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,68 @@ function generatePropTypes(element, attributes) {
'setProps': PropTypes.func`
}

const obsoleteDoc = element => `
* OBSOLETE: <${element}> is included for completeness, but should be avoided
* as it is not supported by any modern browsers.`;

const customDocs = {
basefont: `
* OBSOLETE: <basefont> is included for completeness, but should be avoided
* as it is only supported by Internet Explorer.`,
blink: obsoleteDoc('blink'),
command: obsoleteDoc('command'),
element: obsoleteDoc('element'),
isindex: obsoleteDoc('isindex'),
keygen: `
* DEPRECATED: <keygen> is included for completeness, but should be avoided
* as it is not supported by all browsers and may be removed at any time from
* those that do support it.`,
listing: obsoleteDoc('listing') + ' Use <pre> or <code> instead.',
marquee: `
* DEPRECATED: <marquee> is included for completeness, but should be avoided
* as browsers may remove it at any time.`,
meta: `
* CAUTION: <meta> is included for completeness, but generally will not behave
* as expected since <meta> tags should be static HTML content in the <head> of
* the document. Dash components are dynamic <body> content.`,
multicol: obsoleteDoc('multicol'),
nextid: obsoleteDoc('nextid'),
output: `
* CAUTION: <output> is included for completeness, but its typical usage
* requires the oninput attribute of the enclosing <form> element, which
* is not accessible to Dash.`,
script: `
* CAUTION: <script> is included for completeness, but you cannot execute
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

* JavaScript code by providing it to a <script> element. Use a clientside
* callback for this purpose instead.`,
plaintext: `
* OBSOLETE: <plaintext> is included for completeness, but should be avoided
* as browsers may remove it at any time, and its behavior when added
* dynamically by Dash is not what it would be statically on page load.
* Use <pre> or <code> instead.`,
shadow: `
* DEPRECATED: <shadow> is included for completeness, but should be avoided
* as it is not supported by all browsers and may be removed at any time from
* those that do support it.`,
spacer: obsoleteDoc('spacer'),
title: `
* CAUTION: <title> is included for completeness, but is not expected to
* do anything outside of <head>. Dash components are always created in the
* <body>.`
};

function generateComponent(Component, element, attributes) {
const propTypes = generatePropTypes(element, attributes);

const customDoc = customDocs[element] ? ('\n *' + customDocs[element] + '\n *') : '';

return `
import React from 'react';
import PropTypes from 'prop-types';
import {omit} from 'ramda';

/**
* ${Component} is a wrapper for the <${element}> HTML5 element.
* ${Component} is a wrapper for the <${element}> HTML5 element.${customDoc}
* For detailed attribute info see:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${element}
*/
Expand Down
87 changes: 0 additions & 87 deletions tests/IntegrationTests.py

This file was deleted.

91 changes: 48 additions & 43 deletions tests/test_dash_html_components.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
import unittest
import dash_html_components


class TestDashHtmlComponents(unittest.TestCase):
def test_imports(self):
with open('./scripts/data/elements.txt') as f:
elements = [
s[0].upper() + s[1:] for s in
f.read().split('\n')
]
elements += ['MapEl', 'ObjectEl']
for s in ['Map', 'Object']:
elements.remove(s)

print(dir(dash_html_components))

self.assertEqual(
set([d for d in dir(dash_html_components) if d[0] != '_' and d[0] == d[0].capitalize()]),
set(elements)
)

def test_sample_items(self):
Div = dash_html_components.Div
Img = dash_html_components.Img

layout = Div(
Div(
Img(src='https://plotly.com/~chris/1638.png')
), style={'color': 'red'}
)

self.assertEqual(
repr(layout),
''.join([
"Div(children=Div(Img(src='https://plotly.com/~chris/1638.png')), "
"style={'color': 'red'})"
])
)

self.assertEqual(
layout._namespace, 'dash_html_components'
)
import pytest
import dash_html_components as html


def test_imports():
with open("./scripts/data/elements.txt") as f:
elements = [s[0].upper() + s[1:] for s in f.read().split("\n")]
elements += ["MapEl", "ObjectEl"]
for s in ["Map", "Object"]:
elements.remove(s)

dir_set = set(
[
d
for d in dir(html)
if d[0] != "_" and d[0] == d[0].capitalize()
]
)
assert dir_set == set(elements)


def test_sample_items():
layout = html.Div(
html.Div(html.Img(src="https://plotly.com/~chris/1638.png")),
style={"color": "red"}
)

expected = (
"Div(children=Div(Img(src='https://plotly.com/~chris/1638.png')), "
"style={'color': 'red'})"
)
assert repr(layout) == expected

assert layout._namespace == "dash_html_components"


def test_objectEl():
layout = html.ObjectEl(data="something", **{"data-x": "else"})
assert repr(layout) == "ObjectEl(data='something', data-x='else')"

with pytest.raises(TypeError):
html.ObjectEl(datax="something")


def test_customDocs():
assert "CAUTION" in html.Script.__doc__[:100]
assert "OBSOLETE" in html.Blink.__doc__[:100]
assert "DEPRECATED" in html.Marquee.__doc__[:100]
8 changes: 4 additions & 4 deletions tests/test_dash_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
class TestDashImport(unittest.TestCase):
def setUp(self):
with open('dash.py', 'w') as f:
pass
pass

def tearDown(self):
try:
os.remove('dash.py')
os.remove('dash.pyc')
except OSError:
pass

def test_dash_import(self):
"""Test that program exits if the wrong dash module was imported"""

with self.assertRaises(SystemExit) as cm:
import dash_html_components

Expand Down
Loading