Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone NPM packages and React Native support #335

Merged
merged 27 commits into from
Jul 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8a2f147
STASHING
Jun 20, 2019
62f65a4
STASHING
Jun 20, 2019
ff8f8da
STASHING
Jun 20, 2019
49d1b8b
STASHING
Jun 20, 2019
f324560
STASHING
Jun 21, 2019
2d7d707
STASHING
Jun 21, 2019
def03c0
STASHING
Jun 21, 2019
2dcb4c4
STASHING
Jun 21, 2019
ee7f950
STASHING
Jun 22, 2019
6c7d0c5
Special handling for serializing Infinity too
Jun 22, 2019
a75d8c1
STASHING
Jun 22, 2019
281493b
STASHING
Jun 23, 2019
41a3b72
Added support for saved component filters
Jun 23, 2019
c28e516
Refactored highlighting logic to move outside of Agent
Jun 24, 2019
8417363
Inspecting a native node syncs selection to DevTools tree
Jun 24, 2019
abdd5d7
DevTools tree selection is synced to React Native (when Inspector is …
Jun 24, 2019
dd4aacb
Stashing in-progress work on RN style editor
Jun 25, 2019
022874c
Replaced typed operations arrays with regular arrays to support Hermes
Jun 26, 2019
c75be1a
Inject filters for standalone+website; add RN comments
Jun 26, 2019
5b30680
Cleaned up index HTML so that inputs fully fit the script tag contents
Jul 8, 2019
1623d77
Removed angle brackets (<>) from around Component names
Jul 8, 2019
f204636
Fixed absolute path issue in launchEditor
Jul 9, 2019
fb229b6
Added RN style editor and layout box
Jul 12, 2019
de3107f
Added support for new style attribute
Jul 12, 2019
d227ef9
Whitelist validate style attributes. Add Flipper support.
Jul 12, 2019
e9045e2
Fixed a Flow import
Jul 13, 2019
c6816e2
Changed import in packages/react-devoolts to hopefully satisfy CI Flow
Jul 13, 2019
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/shells/browser/firefox/*.xpi
/shells/browser/firefox/*.pem
/shells/browser/shared/build
/packages/react-devtools-core/dist
/shells/dev/dist
build
node_modules
Expand Down
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ module.exports = api => {
} else {
targets.chrome = minChromeVersion.toString();
targets.firefox = minFirefoxVersion.toString();

// This targets RN/Hermes.
targets.IE = '11';
}
const plugins = [
['@babel/plugin-transform-flow-strip-types'],
Expand Down
284 changes: 284 additions & 0 deletions fixtures/standalone/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>TODO List</title>

<!-- DevTools -->
<script src="http://localhost:8097"></script>

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

<style type="text/css">
.Input {
font-size: 1rem;
padding: 0.25rem;
}

.IconButton {
padding: 0.25rem;
border: none;
background: none;
cursor: pointer;
}

.List {
margin: 0.5rem 0 0;
padding: 0;
}

.ListItem {
list-style-type: none;
}

.Label {
cursor: pointer;
padding: 0.25rem;
color: #555;
}
.Label:hover {
color: #000;
}

.IconButton {
padding: 0.25rem;
border: none;
background: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { Fragment, useCallback, useState } = React;

function List(props) {
const [newItemText, setNewItemText] = useState("");
const [items, setItems] = useState([
{ id: 1, isComplete: true, text: "First" },
{ id: 2, isComplete: true, text: "Second" },
{ id: 3, isComplete: false, text: "Third" }
]);
const [uid, setUID] = useState(4);

const handleClick = useCallback(() => {
if (newItemText !== "") {
setItems([
...items,
{
id: uid,
isComplete: false,
text: newItemText
}
]);
setUID(uid + 1);
setNewItemText("");
}
}, [newItemText, items, uid]);

const handleKeyPress = useCallback(
event => {
if (event.key === "Enter") {
handleClick();
}
},
[handleClick]
);

const handleChange = useCallback(
event => {
setNewItemText(event.currentTarget.value);
},
[setNewItemText]
);

const removeItem = useCallback(
itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
[items]
);

const toggleItem = useCallback(
itemToToggle => {
const index = items.indexOf(itemToToggle);

setItems(
items
.slice(0, index)
.concat({
...itemToToggle,
isComplete: !itemToToggle.isComplete
})
.concat(items.slice(index + 1))
);
},
[items]
);

return (
<Fragment>
<h1>List</h1>
<input
type="text"
placeholder="New list item..."
className="Input"
value={newItemText}
onChange={handleChange}
onKeyPress={handleKeyPress}
/>
<button
className="IconButton"
disabled={newItemText === ""}
onClick={handleClick}
>
<span role="img" aria-label="Add item">
</span>
</button>
<ul className="List">
{items.map(item => (
<ListItem
key={item.id}
item={item}
removeItem={removeItem}
toggleItem={toggleItem}
/>
))}
</ul>
</Fragment>
);
}

function ListItem({ item, removeItem, toggleItem }) {
const handleDelete = useCallback(() => {
removeItem(item);
}, [item, removeItem]);

const handleToggle = useCallback(() => {
toggleItem(item);
}, [item, toggleItem]);

return (
<li className="ListItem">
<button className="IconButton" onClick={handleDelete}>
🗑
</button>
<label className="Label">
<input
className="Input"
checked={item.isComplete}
onChange={handleToggle}
type="checkbox"
/>{" "}
{item.text}
</label>
</li>
);
}

function SimpleValues() {
return (
<ChildComponent
string="abc"
emptyString=""
number={123}
undefined={undefined}
null={null}
nan={NaN}
infinity={Infinity}
true={true}
false={false}
/>
);
}

class Custom {
_number = 42;
get number() {
return this._number;
}
}

function CustomObject() {
return <ChildComponent customObject={new Custom()} />;
}

const object = {
string: "abc",
longString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKJLMNOPQRSTUVWXYZ1234567890",
emptyString: "",
number: 123,
boolean: true,
undefined: undefined,
null: null
};

function ObjectProps() {
return (
<ChildComponent
object={{
outer: {
inner: object
}
}}
array={["first", "second", "third"]}
objectInArray={[object]}
arrayInObject={{ array: ["first", "second", "third"] }}
deepObject={{
// Known limitation: we won't go deeper than several levels.
// In the future, we might offer a way to request deeper access on demand.
a: {
b: {
c: {
d: {
e: {
f: {
g: {
h: {
i: {
j: 10
}
}
}
}
}
}
}
}
}
}}
/>
);
}

function ChildComponent(props: any) {
return null;
}

function InspectableElements() {
return (
<Fragment>
<SimpleValues />
<ObjectProps />
<CustomObject />
</Fragment>
);
}

function App() {
return (
<Fragment>
<List />
<InspectableElements />
</Fragment>
);
}

ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
</html>
94 changes: 94 additions & 0 deletions flow-typed/chrome.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// @flow

declare var chrome: {
devtools: {
network: {
onNavigated: {
addListener: (cb: (url: string) => void) => void,
removeListener: (cb: () => void) => void,
},
},
inspectedWindow: {
eval: (code: string, cb?: (res: any, err: ?Object) => any) => void,
tabId: number,
},
panels: {
create: (
title: string,
icon: string,
filename: string,
cb: (panel: {
onHidden: {
addListener: (cb: (window: Object) => void) => void,
},
onShown: {
addListener: (cb: (window: Object) => void) => void,
},
}) => void
) => void,
themeName: ?string,
},
},
tabs: {
create: (options: Object) => void,
executeScript: (tabId: number, options: Object, fn: () => void) => void,
onUpdated: {
addListener: (
fn: (tabId: number, changeInfo: Object, tab: Object) => void
) => void,
},
query: (options: Object, fn: (tabArray: Array<Object>) => void) => void,
},
browserAction: {
setIcon: (options: {
tabId: number,
path: { [key: string]: string },
}) => void,
setPopup: (options: {
tabId: number,
popup: string,
}) => void,
},
runtime: {
getURL: (path: string) => string,
sendMessage: (config: Object) => void,
connect: (
config: Object
) => {
disconnect: () => void,
onMessage: {
addListener: (fn: (message: Object) => void) => void,
},
onDisconnect: {
addListener: (fn: (message: Object) => void) => void,
},
postMessage: (data: Object) => void,
},
onConnect: {
addListener: (
fn: (port: {
name: string,
sender: {
tab: {
id: number,
url: string,
},
},
}) => void
) => void,
},
onMessage: {
addListener: (
fn: (
req: Object,
sender: {
url: string,
tab: {
id: number,
},
}
) => void
) => void,
},
},
};
Loading