Socket
Socket
Sign inDemoInstall

devtools-reps

Package Overview
Dependencies
21
Maintainers
11
Versions
39
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.22.0 to 0.23.0

src/object-inspector/tests/component/__snapshots__/keyboard-navigation.js.snap

6

package.json
{
"name": "devtools-reps",
"version": "0.22.0",
"version": "0.23.0",
"description": "Devtools Reps",

@@ -29,3 +29,3 @@ "main": "src/index.js",

"classnames": "^2.2.5",
"devtools-components": "^0.4.1",
"devtools-components": "^0.6.0",
"lodash": "^4.17.2",

@@ -48,3 +48,3 @@ "prop-types": "^15.6.0",

"devtools-license-check": "^0.5.1",
"devtools-modules": "^0.0.34",
"devtools-modules": "^0.0.35",
"enzyme": "^3.3.0",

@@ -51,0 +51,0 @@ "enzyme-adapter-react-16": "^1.1.1",

@@ -56,2 +56,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

function createLongStringClient(grip) {
return function ({dispatch, client}) {
return client.getLongStringClient(grip);
};
}
function releaseActor(actor) {

@@ -69,3 +75,4 @@ return function ({dispatch, client}) {

createObjectClient,
createLongStringClient,
releaseActor,
};

@@ -8,5 +8,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

module.exports = Object.assign({},
expressions,
input,
);
module.exports = {
...expressions,
...input,
};

@@ -34,2 +34,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

createObjectClient: PropTypes.func.isRequired,
createLongStringClient: PropTypes.func.isRequired,
releaseActor: PropTypes.func.isRequired,

@@ -59,2 +60,3 @@ };

createObjectClient,
createLongStringClient,
releaseActor,

@@ -78,2 +80,3 @@ } = this.props;

createObjectClient,
createLongStringClient,
releaseActor,

@@ -80,0 +83,0 @@ })

@@ -20,2 +20,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

createObjectClient: PropTypes.func.isRequired,
createLongStringClient: PropTypes.func.isRequired,
releaseActor: PropTypes.func.isRequired,

@@ -63,2 +64,3 @@ };

createObjectClient,
createLongStringClient,
releaseActor,

@@ -83,5 +85,12 @@ } = this.props;

createObjectClient,
createLongStringClient,
releaseActor,
mode: MODE[modeKey],
onInspectIconClick: nodeFront => console.log("inspectIcon click", nodeFront),
disableFocus: false,
// The following properties are optional function props called by the
// objectInspector on some occasions. Here we pass dull functions that only
// logs the parameters with which the callback was called.
onCmdCtrlClick: (node, { depth, event, focused, expanded }) =>
console.log("CmdCtrlClick", {node, depth, event, focused, expanded}),
onInspectIconClick: nodeFront => console.log("inspectIcon click", {nodeFront}),
onViewSourceInDebugger: location =>

@@ -88,0 +97,0 @@ console.log("onViewSourceInDebugger", {location}),

@@ -20,2 +20,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

createObjectClient: PropTypes.func.isRequired,
createLongStringClient: PropTypes.func.isRequired,
releaseActor: PropTypes.func.isRequired,

@@ -31,2 +32,3 @@ };

createObjectClient,
createLongStringClient,
releaseActor,

@@ -46,2 +48,3 @@ } = this.props;

createObjectClient,
createLongStringClient,
releaseActor,

@@ -48,0 +51,0 @@ })

@@ -6,2 +6,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

// globals window, document
require("../reps/reps.css");

@@ -38,2 +39,6 @@

getLongStringClient: function (grip) {
return connection.tabConnection.tabTarget.activeConsole.longString(grip);
},
releaseActor: function (actor) {

@@ -45,3 +50,3 @@ return connection.tabConnection.debuggerClient.release(actor);

let store = configureStore({
makeThunkArgs: (args, state) => Object.assign({}, args, { client }),
makeThunkArgs: (args, state) => ({ ...args, client }),
client,

@@ -48,0 +53,0 @@ });

@@ -18,3 +18,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

return createStore(
combineReducers(Object.assign({client}, reducers)),
combineReducers({ client, ...reducers }),
applyMiddleware(

@@ -21,0 +21,0 @@ thunk(options.makeThunkArgs),

@@ -8,7 +8,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

import type {
CreateLongStringClient,
CreateObjectClient,
GripProperties,
LoadedProperties,
Node,
ObjectClient,
RdpGrip,
Props,
ReduxAction,

@@ -36,3 +37,4 @@ } from "./types";

loadedProperties : LoadedProperties,
createObjectClient : (RdpGrip) => ObjectClient
createObjectClient : CreateObjectClient,
createLongStringClient : CreateLongStringClient
) {

@@ -46,3 +48,4 @@ return async ({dispatch} : ThunkArg) => {

if (!loadedProperties.has(node.path)) {
dispatch(nodeLoadProperties(node, actor, loadedProperties, createObjectClient));
dispatch(nodeLoadProperties(node, actor, loadedProperties, createObjectClient,
createLongStringClient));
}

@@ -73,3 +76,4 @@ };

loadedProperties : LoadedProperties,
createObjectClient : (RdpGrip) => ObjectClient
createObjectClient : CreateObjectClient,
createLongStringClient : CreateLongStringClient
) {

@@ -79,3 +83,4 @@ return async ({dispatch} : ThunkArg) => {

const properties =
await loadItemProperties(item, createObjectClient, loadedProperties);
await loadItemProperties(item, createObjectClient, createLongStringClient,
loadedProperties);
dispatch(nodePropertiesLoaded(item, actor, properties));

@@ -99,3 +104,27 @@ } catch (e) {

/*
* This action is dispatched when the `roots` prop, provided by a consumer of the
* ObjectInspector (inspector, console, …), is modified. It will clean the internal
* state properties (expandedPaths, loadedProperties, …) and release the actors consumed
* with the previous roots.
* It takes a props argument which reflects what is passed by the upper-level consumer.
*/
function rootsChanged(props: Props) {
return {
type: "ROOTS_CHANGED",
data: props,
};
}
/*
* This action will reset the `forceUpdate` flag in the state.
*/
function forceUpdated() {
return {
type: "FORCE_UPDATED",
};
}
module.exports = {
forceUpdated,
nodeExpand,

@@ -106,2 +135,3 @@ nodeCollapse,

nodePropertiesLoaded,
rootsChanged,
};

@@ -46,2 +46,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

nodeIsWindow,
nodeIsLongString,
nodeHasFullText
} = Utils.node;

@@ -106,2 +108,3 @@

expandedPaths,
focusedItem,
loadedProperties,

@@ -112,5 +115,18 @@ roots,

if (roots !== nextProps.roots) {
// Since the roots changed, we assume the properties did as well. Thus we can clear
// the cachedNodes to avoid bugs and memory leaks.
// Since the roots changed, we assume the properties did as well, so we need to
// cleanup the component internal state.
// We can clear the cachedNodes to avoid bugs and memory leaks.
this.cachedNodes.clear();
// The rootsChanged action will be handled in a middleware to release the actors
// of the old roots, as well as cleanup the state properties (expandedPaths,
// loadedProperties, …).
this.props.rootsChanged(nextProps);
// We don't render right away since the state is going to be changed by the
// rootsChanged action. The `state.forceUpdate` flag will be set to `true` so we
// can execute a new render cycle with the cleaned state.
return false;
}
if (nextProps.forceUpdate === true) {
return true;

@@ -123,2 +139,3 @@ }

// - OR the expanded paths number did not changed, but old and new sets differ
// - OR the focused node changed.
return loadedProperties.size !== nextProps.loadedProperties.size

@@ -132,5 +149,13 @@ || (

[...nextProps.expandedPaths].some(key => !expandedPaths.has(key))
);
)
|| focusedItem !== nextProps.focusedItem;
}
componentDidUpdate(prevProps) {
if (this.props.forceUpdate) {
// If the component was updated, we can then reset the forceUpdate flag.
this.props.forceUpdated();
}
}
componentWillUnmount() {

@@ -181,2 +206,3 @@ const { releaseActor } = this.props;

createObjectClient,
createLongStringClient,
loadedProperties,

@@ -196,3 +222,4 @@ nodeExpand,

const actor = isRoot || !value ? null : value.actor;
nodeExpand(item, actor, loadedProperties, createObjectClient);
nodeExpand(item, actor, loadedProperties, createObjectClient,
createLongStringClient);
} else {

@@ -205,8 +232,13 @@ nodeCollapse(item);

const {
focusable = true,
focusedItem,
nodeFocus,
onFocus,
} = this.props;
if (focusedItem !== item && onFocus) {
onFocus(item);
if (focusable && focusedItem !== item) {
nodeFocus(item);
if (focusedItem !== item && onFocus) {
onFocus(item);
}
}

@@ -219,3 +251,3 @@ }

}) {
let label = item.name;
const label = item.name;
const isPrimitive = nodeIsPrimitive(item);

@@ -296,7 +328,8 @@

|| nodeIsMapEntry(item)
|| nodeIsLongString(item)
|| isPrimitive
) {
let repsProp = {...this.props};
let repProps = {...this.props};
if (depth > 0) {
repsProp.mode = this.props.mode === MODE.LONG
repProps.mode = this.props.mode === MODE.LONG
? MODE.SHORT

@@ -306,8 +339,14 @@ : MODE.TINY;

if (expanded) {
repsProp.mode = MODE.TINY;
repProps.mode = MODE.TINY;
}
if (nodeIsLongString(item)) {
repProps.member = {
open: nodeHasFullText(item) && expanded
};
}
return {
label,
value: Utils.renderRep(item, repsProp)
value: Utils.renderRep(item, repProps)
};

@@ -365,2 +404,3 @@ }

const {
onCmdCtrlClick,
onDoubleClick,

@@ -385,10 +425,25 @@ dimTopLevelWindow,

onClick: e => {
e.stopPropagation();
// If the user selected text, bail out.
if (Utils.selection.documentHasSelection()) {
if (e.metaKey && onCmdCtrlClick) {
onCmdCtrlClick(item, {
depth,
event: e,
focused,
expanded,
});
e.stopPropagation();
return;
}
this.setExpanded(item, !expanded);
// If this click happened because the user selected some text, bail out.
// Note that if the user selected some text before and then clicks here,
// the previously selected text will be first unselected, unless the user
// clicked on the arrow itself. Indeed because the arrow is an image, clicking on
// it does not remove any existing text selection. So we need to also check if
// teh arrow was clicked.
if (
Utils.selection.documentHasSelection()
&& !(e.target && e.target.matches && e.target.matches(".arrow"))
) {
e.stopPropagation();
}
},

@@ -437,3 +492,3 @@ };

autoExpandDepth = 1,
disabledFocus,
focusable = true,
disableWrap = false,

@@ -453,3 +508,2 @@ expandedPaths,

autoExpandDepth,
disabledFocus,

@@ -467,3 +521,3 @@ isExpanded: item => expandedPaths && expandedPaths.has(item.path),

onCollapse: item => this.setExpanded(item, false),
onFocus: this.focusItem,
onFocus: focusable ? this.focusItem : null,

@@ -479,4 +533,8 @@ renderItem: this.renderTreeItem

expandedPaths: state.expandedPaths,
focusedItem: state.focusedItem,
// If the root changes, we want to pass a possibly new focusedItem property
focusedItem: state.roots !== props.roots
? props.focusedItem
: state.focusedItem,
loadedProperties: state.loadedProperties,
forceUpdate: state.forceUpdate,
};

@@ -483,0 +541,0 @@ }

@@ -43,2 +43,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

if (type === "NODE_FOCUS") {
if (state.focusedItem === data.node) {
return state;
}
return cloneState({

@@ -49,2 +53,8 @@ focusedItem: data.node

if (type === "FORCE_UPDATED") {
return cloneState({
forceUpdate: false,
});
}
return state;

@@ -51,0 +61,0 @@ }

@@ -6,3 +6,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

// @flow
const { applyMiddleware, createStore } = require("redux");
const { applyMiddleware, createStore, compose } = require("redux");
const {thunk} = require("../shared/redux/middleware/thunk");

@@ -23,2 +23,3 @@ const {waitUntilService} = require("../shared/redux/middleware/waitUntilService");

loadedProperties: new Map(),
forceUpdated: false,
...overrides,

@@ -28,4 +29,29 @@ };

function enableStateReinitializer(props) {
return next => (innerReducer, initialState, enhancer) => {
function reinitializerEnhancer(state, action) {
if (action.type !== "ROOTS_CHANGED") {
return innerReducer(state, action);
}
if (props.releaseActor && initialState.actors) {
initialState.actors.forEach(props.releaseActor);
}
return {
...action.data,
actors: new Set(),
expandedPaths: new Set(),
loadedProperties: new Map(),
// Indicates to the component that we do want to render on the next render cycle.
forceUpdate: true,
};
}
return next(reinitializerEnhancer, initialState, enhancer);
};
}
module.exports = (props : Props) => {
const middlewares = [thunk];
if (props.injectWaitService) {

@@ -38,4 +64,7 @@ middlewares.push(waitUntilService);

createInitialState(props),
applyMiddleware(...middlewares)
compose(
applyMiddleware(...middlewares),
enableStateReinitializer(props)
)
);
};

@@ -277,11 +277,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

it("updates when the root changes", () => {
it("updates when the root changes", async () => {
let root = {
path: "root",
contents: {
value: gripRepStubs.get("testMoreThanMaxProps")
}
};
let oi = mount(ObjectInspector(generateDefaults({
roots: [{
path: "root",
contents: {
value: gripRepStubs.get("testMoreThanMaxProps")
}
}],
roots: [root],
mode: MODE.LONG,
focusedItem: root,
injectWaitService: true,
})));

@@ -291,10 +294,16 @@

root = {
path: "root-2",
contents: {
value: gripRepStubs.get("testMaxProps")
}
};
let onComponentUpdated = waitForDispatch(oi.instance().getStore(), "FORCE_UPDATED");
oi.setProps({
roots: [{
path: "root-2",
contents: {
value: gripRepStubs.get("testMaxProps")
}
}]
roots: [root],
focusedItem: root,
});
await onComponentUpdated;
oi.update();
expect(formatObjectInspector(oi)).toMatchSnapshot();

@@ -321,6 +330,8 @@ });

mode: MODE.LONG,
injectWaitService: true,
})));
oi.find(".node").at(0).simulate("click");
const oldTree = formatObjectInspector(oi);
const oldTree = formatObjectInspector(oi);
let onComponentUpdated = waitForDispatch(oi.instance().getStore(), "FORCE_UPDATED");
oi.setProps({

@@ -339,4 +350,6 @@ roots: [{

await onComponentUpdated;
oi.update();
expect(formatObjectInspector(oi)).not.toBe(oldTree);
});
});

@@ -44,2 +44,23 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

it("does not call the onFocus when given focus but focusable is false", () => {
const stub = gripRepStubs.get("testMaxProps");
const onFocus = jest.fn();
const oi = mount(ObjectInspector(generateDefaults({
focusable: true,
roots: [{
path: "root",
contents: {
value: stub
}
}],
onFocus,
})));
const node = oi.find(".node").first();
node.simulate("focus");
expect(onFocus.mock.calls.length).toBe(0);
});
it("calls the onDoubleClick prop function when provided one and double clicked", () => {

@@ -65,2 +86,22 @@ const stub = gripRepStubs.get("testMaxProps");

it("calls the onCmdCtrlClick prop function when provided and cmd/ctrl-clicked", () => {
const stub = gripRepStubs.get("testMaxProps");
const onCmdCtrlClick = jest.fn();
const oi = mount(ObjectInspector(generateDefaults({
roots: [{
path: "root",
contents: {
value: stub
}
}],
onCmdCtrlClick,
})));
const node = oi.find(".node").first();
node.simulate("click", { metaKey: true });
expect(onCmdCtrlClick.mock.calls.length).toBe(1);
});
it("calls the onLabel prop function when provided one and label clicked", () => {

@@ -67,0 +108,0 @@ const stub = gripRepStubs.get("testMaxProps");

@@ -208,2 +208,25 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

it("does expand if the user selected some text and clicked the arrow", async () => {
const wrapper = mount(ObjectInspector(generateDefaults({
injectWaitService: true,
loadedProperties: new Map([
["root-1", gripPropertiesStubs.get("proto-properties-symbols")]
])
})));
const store = wrapper.instance().getStore();
expect(formatObjectInspector(wrapper)).toMatchSnapshot();
let nodes = wrapper.find(".node");
// Set a selection using the mock.
getSelection().setMockSelection("test");
const root1 = nodes.at(0);
root1.find("img.arrow").simulate("click");
expect(store.getState().expandedPaths.has("root-1")).toBeTruthy();
expect(formatObjectInspector(wrapper)).toMatchSnapshot();
// Clear the selection for other tests.
getSelection().setMockSelection();
});
it("does not throw when expanding a block node", async () => {

@@ -210,0 +233,0 @@ const blockNode = createNode({

@@ -15,2 +15,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

const stub = gripRepStubs.get("testMoreThanMaxProps");
const {
waitForDispatch,
} = require("../test-utils");

@@ -46,2 +49,30 @@ function generateDefaults(overrides) {

});
it("calls release actors when the roots prop changed", async () => {
const releaseActor = jest.fn();
const props = generateDefaults({
releaseActor,
actors: new Set(["actor 1", "actor 2"]),
injectWaitService: true,
});
const oi = ObjectInspector(props);
const wrapper = mount(oi);
const store = wrapper.instance().getStore();
const onRootsChanged = waitForDispatch(store, "ROOTS_CHANGED");
wrapper.setProps({
roots: [{
path: "root-2",
contents: {
value: gripRepStubs.get("testMaxProps")
}
}]
});
await onRootsChanged;
expect(releaseActor.mock.calls.length).toBe(2);
expect(releaseActor.mock.calls[0][0]).toBe("actor 1");
expect(releaseActor.mock.calls[1][0]).toBe("actor 2");
});
});

@@ -26,3 +26,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

function formatObjectInspector(wrapper: Object) {
return wrapper.find(".tree-node")
const hasFocusedNode = wrapper.find(".tree-node.focused").length > 0;
const textTree = wrapper.find(".tree-node")
.map(node => {

@@ -42,5 +43,14 @@ const indentStr = "| ".repeat((node.prop("aria-level") || 1) - 1);

: "";
return `${indentStr}${arrowStr}${icon}${getSanitizedNodeText(node)}`;
let text = `${indentStr}${arrowStr}${icon}${getSanitizedNodeText(node)}`;
if (!hasFocusedNode) {
return text;
}
return node.hasClass("focused")
? `[ ${text} ]`
: ` ${text}`;
})
.join("\n");
// Wrap the text representation in new lines so it keeps alignment between
// tree nodes.
return `\n${textTree}\n`;
}

@@ -47,0 +57,0 @@

@@ -9,3 +9,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

safeGetterValues?: Object,
prototype?: Object
prototype?: Object,
fullText?: string,
};

@@ -55,2 +56,17 @@

export type LongStringClient = {
substring: (
start: number,
end: number,
response: {
substring?: string,
error?: Error,
message?: string,
}) => void,
}
export type CreateObjectClient = (RdpGrip) => ObjectClient;
export type CreateLongStringClient = (RdpGrip) => LongStringClient;
export type CachedNodes = Map<Path, Array<Node>>;

@@ -69,3 +85,3 @@

autoExpandDepth: number,
disabledFocus: boolean,
focusable: boolean,
itemHeight: number,

@@ -78,3 +94,4 @@ inline: boolean,

releaseActor: string => void,
createObjectClient: RdpGrip => ObjectClient,
createObjectClient: CreateObjectClient,
createLongStringClient: CreateLongStringClient,
onFocus: ?(Node) => any,

@@ -89,2 +106,11 @@ onDoubleClick: ?(

) => any,
onCmdCtrlClick: ?(
item: Node,
options: {
depth: number,
event: SyntheticEvent,
focused: boolean,
expanded: boolean
}
) => any,
onLabelClick: ?(

@@ -91,0 +117,0 @@ item: Node,

@@ -10,2 +10,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

PropertiesIterator,
NodeContents, LongStringClient,
} from "../types";

@@ -84,2 +85,24 @@

async function getFullText(
longStringClient: LongStringClient,
object: NodeContents,
) : Promise<{fullText?: string}> {
const { initial, length } = object;
return new Promise((resolve, reject) => {
longStringClient.substring(initial.length, length, response => {
if (response.error) {
console.error("LongStringClient.substring",
response.error + ": " + response.message);
reject({});
return;
}
resolve({
fullText: initial + response.substring
});
});
});
}
function iteratorSlice(

@@ -94,2 +117,6 @@ iterator: PropertiesIterator,

: iterator.count;
if (count === 0) {
return Promise.resolve({});
}
return iterator.slice(start, count);

@@ -104,2 +131,3 @@ }

getPrototype,
getFullText,
};

@@ -11,2 +11,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

enumSymbols,
getFullText,
} = require("./client");

@@ -28,10 +29,11 @@

nodeNeedsNumericalBuckets,
nodeIsLongString
} = require("./node");
import type {
CreateLongStringClient,
CreateObjectClient,
GripProperties,
LoadedProperties,
Node,
ObjectClient,
RdpGrip,
} from "../types";

@@ -41,3 +43,4 @@

item : Node,
createObjectClient : (RdpGrip) => ObjectClient,
createObjectClient : CreateObjectClient,
createLongStringClient : CreateLongStringClient,
loadedProperties : LoadedProperties,

@@ -76,2 +79,6 @@ ) : Promise<GripProperties> {

if (shouldLoadItemFullText(item, loadedProperties)) {
promises.push(getFullText(createLongStringClient(value), value));
}
return Promise.all(promises).then(mergeResponses);

@@ -95,2 +102,6 @@ }

}
if (response.fullText) {
data.fullText = response.fullText;
}
}

@@ -162,3 +173,4 @@

&& !nodeHasAccessors(item)
&& !nodeIsPrimitive(item);
&& !nodeIsPrimitive(item)
&& !nodeIsLongString(item);
}

@@ -180,5 +192,13 @@

&& !nodeIsPrimitive(item)
&& !nodeIsLongString(item)
&& !nodeIsProxy(item);
}
function shouldLoadItemFullText(
item: Node,
loadedProperties: LoadedProperties = new Map()
) {
return !loadedProperties.has(item.path) && nodeIsLongString(item);
}
module.exports = {

@@ -192,2 +212,3 @@ loadItemProperties,

shouldLoadItemSymbols,
shouldLoadItemFullText
};

@@ -6,3 +6,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

// @flow
const { get, has } = require("lodash");
const { maybeEscapePropertyName } = require("../../reps/rep-utils");

@@ -14,2 +14,3 @@ const ArrayRep = require("../../reps/array");

const ErrorRep = require("../../reps/error");
const { isLongString } = require("../../reps/string");

@@ -58,8 +59,8 @@ const MAX_NUMERICAL_PROPERTIES = 100;

) : RdpGrip | NodeContents {
if (has(item, "contents.value")) {
return get(item, "contents.value");
if (item && item.contents && item.contents.hasOwnProperty("value")) {
return item.contents.value;
}
if (has(item, "contents.getterValue")) {
return get(item, "contents.getterValue", undefined);
if (item && item.contents && item.contents.hasOwnProperty("getterValue")) {
return item.contents.getterValue;
}

@@ -147,3 +148,4 @@

&& !nodeHasAccessors(item)
&& !nodeIsBucket(item);
&& !nodeIsBucket(item)
&& !nodeIsLongString(item);
}

@@ -220,2 +222,15 @@

function nodeIsLongString(
item: Node
) : boolean {
return isLongString(getValue(item));
}
function nodeHasFullText(
item: Node
) : boolean {
const value = getValue(item);
return nodeIsLongString(item) && value.hasOwnProperty("fullText");
}
function nodeHasAccessors(item: Node) : boolean {

@@ -244,3 +259,4 @@ return !!getNodeGetter(item) || !!getNodeSetter(item);

|| value.class === "WeakMap"
|| value.class === "WeakSet";
|| value.class === "WeakSet"
|| value.class === "Storage";
}

@@ -412,7 +428,11 @@

function getNodeGetter(item: Node): ?Object {
return get(item, "contents.get", undefined);
return item && item.contents
? item.contents.get
: undefined;
}
function getNodeSetter(item: Node): ?Object {
return get(item, "contents.set", undefined);
return item && item.contents
? item.contents.set
: undefined;
}

@@ -609,2 +629,17 @@

function setNodeFullText(
loadedProps: GripProperties,
node: Node
) : Node {
if (nodeHasFullText(node)) {
return node;
}
if (nodeIsLongString(node)) {
node.contents.value.fullText = loadedProps.fullText;
}
return node;
}
function makeNodeForPrototype(

@@ -734,5 +769,9 @@ objProps: GripProperties,

if (nodeIsLongString(item) && hasLoadedProps) {
// Set longString object's fullText to fetched one.
return addToCache(setNodeFullText(loadedProps, item));
}
if (nodeNeedsNumericalBuckets(item) && hasLoadedProps) {
// Even if we have numerical buckets, we should have loaded non indexed properties,
// like length for example.
const bucketNodes = makeNumericalBuckets(item);

@@ -837,2 +876,4 @@ return addToCache(bucketNodes.concat(makeNodesForProperties(loadedProps, item)));

nodeIsError,
nodeIsLongString,
nodeHasFullText,
nodeIsFunction,

@@ -839,0 +880,0 @@ nodeIsGetter,

@@ -5,4 +5,2 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

const {ELEMENT_NODE} = require("../../shared/dom-node-constants");
function documentHasSelection() : boolean {

@@ -14,19 +12,2 @@ const selection = getSelection();

const {
anchorNode,
focusNode,
} = selection;
// When clicking the arrow, which is an inline svg element, the selection do have a type
// of "Range". We need to have an explicit case when the anchor and the focus node are
// the same and they have an arrow ancestor.
if (
focusNode &&
focusNode === anchorNode &&
focusNode.nodeType == ELEMENT_NODE &&
focusNode.closest(".arrow")
) {
return false;
}
return selection.type === "Range";

@@ -33,0 +14,0 @@ }

@@ -25,4 +25,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

object: PropTypes.object.isRequired,
inspectIconTitle: PropTypes.string,
// @TODO Change this to Object.values once it's supported in Node's version of V8
mode: PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
onDOMNodeClick: PropTypes.func,
onDOMNodeMouseOver: PropTypes.func,

@@ -36,3 +38,5 @@ onDOMNodeMouseOut: PropTypes.func,

object,
inspectIconTitle,
mode,
onDOMNodeClick,
onDOMNodeMouseOver,

@@ -52,2 +56,8 @@ onDOMNodeMouseOut,

if (isInTree) {
if (onDOMNodeClick) {
Object.assign(baseConfig, {
onClick: _ => onDOMNodeClick(object)
});
}
if (onDOMNodeMouseOver) {

@@ -69,4 +79,10 @@ Object.assign(baseConfig, {

// TODO: Localize this with "openNodeInInspector" when Bug 1317038 lands
title: "Click to select the node in the inspector",
onClick: (e) => onInspectIconClick(object, e)
title: inspectIconTitle || "Click to select the node in the inspector",
onClick: e => {
if (onDOMNodeClick) {
e.stopPropagation();
}
onInspectIconClick(object, e);
}
});

@@ -83,3 +99,8 @@ }

function getElements(grip, mode) {
let {attributes, nodeName} = grip.preview;
let {
attributes,
nodeName,
isAfterPseudoElement,
isBeforePseudoElement,
} = grip.preview;
const nodeNameElement = span({

@@ -89,2 +110,8 @@ className: "tag-name"

if (isAfterPseudoElement || isBeforePseudoElement) {
return [
span({ className: "attrName" }, `::${ isAfterPseudoElement ? "after" : "before" }`)
];
}
if (mode === MODE.TINY) {

@@ -109,2 +136,3 @@ let elements = [nodeNameElement];

}
let attributeKeys = Object.keys(attributes);

@@ -111,0 +139,0 @@ if (attributeKeys.includes("class")) {

@@ -53,3 +53,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

}
return (grip && grip.type === "mapEntry" && grip.preview);
return grip &&
(grip.type === "mapEntry" || grip.type === "storageEntry") &&
grip.preview;
}

@@ -56,0 +58,0 @@

@@ -6,3 +6,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

// Dependencies
const validProtocols = /^(http|https|ftp|data|resource|chrome):/i;
const validProtocols = /(http|https|ftp|data|resource|chrome):/i;
const tokenSplitRegex = /(\s|\'|\"|\\)+/;

@@ -363,8 +363,8 @@ const ELLIPSIS = "\u2026";

function containsURL(grip) {
if (typeof grip !== "string") {
// An URL can't be shorter than 5 char (e.g. "ftp:").
if (typeof grip !== "string" || grip.length < 5) {
return false;
}
let tokens = grip.split(tokenSplitRegex);
return tokens.some(isURL);
return validProtocols.test(grip);
}

@@ -371,0 +371,0 @@

@@ -77,3 +77,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

/**
* Generic rep that is using for rendering native JS types or an object.
* Generic rep that is used for rendering native JS types or an object.
* The right template used for rendering is picked automatically according

@@ -102,3 +102,3 @@ * to the current value type. The value must be passed is as 'object'

*
* @param defaultObject {React.Component} The default template
* @param defaultRep {React.Component} The default template
* that should be used to render given object if none is found.

@@ -105,0 +105,0 @@ *

@@ -32,3 +32,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

cropLimit: PropTypes.number.isRequired,
member: PropTypes.string,
member: PropTypes.object,
object: PropTypes.object.isRequired,

@@ -48,3 +48,3 @@ openLink: PropTypes.func,

member,
openLink,
openLink
} = props;

@@ -55,3 +55,4 @@

const isLong = isLongString(object);
const shouldCrop = (!member || !member.open) && cropLimit && text.length > cropLimit;
const isOpen = member && member.open;
const shouldCrop = !isOpen && cropLimit && text.length > cropLimit;

@@ -63,2 +64,7 @@ if (isLong) {

}, text);
const { fullText } = object;
if (isOpen && fullText) {
text = fullText;
}
}

@@ -97,7 +103,6 @@

shouldCrop,
cropLimit
cropLimit,
} = opts;
const {
fullText,
initial,

@@ -109,3 +114,3 @@ length,

? initial.substring(0, cropLimit)
: fullText || initial;
: initial;

@@ -112,0 +117,0 @@ if (text.length < length) {

@@ -235,2 +235,28 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

stubs.set("BeforePseudoElement", {
"type": "object",
"actor": "server1.conn1.child1/obj27",
"preview": {
"kind": "DOMNode",
"nodeType": 1,
"nodeName": "_moz_generated_content_before",
"attributes": {},
"attributesLength": 0,
"isBeforePseudoElement": true,
}
});
stubs.set("AfterPseudoElement", {
"type": "object",
"actor": "server1.conn1.child1/obj28",
"preview": {
"kind": "DOMNode",
"nodeType": 1,
"nodeName": "_moz_generated_content_after",
"attributes": {},
"attributesLength": 0,
"isAfterPseudoElement": true,
}
});
module.exports = stubs;

@@ -123,2 +123,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

it("calls the expected function when click is fired on Rep", () => {
const onDOMNodeClick = jest.fn();
const renderedComponent = shallow(ElementNode.rep({
object: stub,
onDOMNodeClick
}));
renderedComponent.simulate("click");
expect(onDOMNodeClick.mock.calls.length).toEqual(1);
});
it("calls the expected function when mouseout is fired on Rep", () => {

@@ -349,1 +361,68 @@ const onDOMNodeMouseOut = jest.fn();

});
describe("ElementNode - : Before pseudo element", () => {
const stub = stubs.get("BeforePseudoElement");
it("selects ElementNode Rep", () => {
expect(getRep(stub)).toBe(ElementNode.rep);
});
it("renders with expected text content", () => {
const renderedComponent = shallow(ElementNode.rep({
object: stub
}));
expect(renderedComponent.text()).toEqual("::before");
});
it("renders with expected text content in tiny mode", () => {
const renderedComponent = shallow(ElementNode.rep({
object: stub,
mode: MODE.TINY
}));
expect(renderedComponent.text()).toEqual("::before");
});
});
describe("ElementNode - After pseudo element", () => {
const stub = stubs.get("AfterPseudoElement");
it("selects ElementNode Rep", () => {
expect(getRep(stub)).toBe(ElementNode.rep);
});
it("renders with expected text content", () => {
const renderedComponent = shallow(ElementNode.rep({
object: stub
}));
expect(renderedComponent.text()).toEqual("::after");
});
it("renders with expected text content in tiny mode", () => {
const renderedComponent = shallow(ElementNode.rep({
object: stub,
mode: MODE.TINY
}));
expect(renderedComponent.text()).toEqual("::after");
});
});
describe("ElementNode - Inspect icon title", () => {
const stub = stubs.get("Node");
it("renders with expected title", () => {
const inspectIconTitle = "inspect icon title";
const renderedComponent = shallow(ElementNode.rep({
inspectIconTitle,
object: stub,
onInspectIconClick: jest.fn(),
}));
const iconNode = renderedComponent.find(".open-inspector");
expect(iconNode.prop("title")).toEqual(inspectIconTitle);
});
});

@@ -12,2 +12,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

const {
ELLIPSIS,
} = require("../rep-utils");
const {
expectActorAttribute,

@@ -36,3 +40,4 @@ } = require("./test-helpers");

expect(renderedComponent.text()).toEqual(quoteNewlines(`"${stub.initial}…"`));
expect(renderedComponent.text())
.toEqual(quoteNewlines(`"${stub.initial}${ELLIPSIS}"`));
expectActorAttribute(renderedComponent, stub.actor);

@@ -49,3 +54,3 @@ });

expect(renderedComponent.text()).toEqual(`"a\\naaaaaaaaaaaaaaaaaa…"`);
expect(renderedComponent.text()).toEqual(`"a\\naaaaaaaaaaaaaaaaaa${ELLIPSIS}"`);
});

@@ -62,3 +67,3 @@

expect(renderedComponent.text())
.toEqual(quoteNewlines(`"${stub.initial}…"`));
.toEqual(quoteNewlines(`"${stub.initial}${ELLIPSIS}"`));
});

@@ -86,3 +91,3 @@

expect(renderedComponent.text()).toEqual(`"a\\naaaaaaaaaaaaaaaaaa…"`);
expect(renderedComponent.text()).toEqual(`"a\\naaaaaaaaaaaaaaaaaa${ELLIPSIS}"`);
});

@@ -100,4 +105,5 @@

.toEqual('<span data-link-actor-id="server1.conn1.child1/longString58" ' +
'class="objectBox objectBox-string">a\naaaaaaaaaaaaaaaaaa…</span>');
`class="objectBox objectBox-string">a\naaaaaaaaaaaaaaaaaa${ELLIPSIS}` +
"</span>");
});
});

@@ -6,2 +6,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

const { shallow } = require("enzyme");
const { ELLIPSIS } = require("../rep-utils");
const { REPS } = require("../rep");

@@ -22,3 +23,3 @@ const { Rep } = REPS;

},
result: "\"aaaaaaaaa…cccccc\\n\""
result: `\"aaaaaaaaa${ELLIPSIS}cccccc\\n\"`
}, {

@@ -75,2 +76,27 @@ name: "testMultilineOpen",

result: "\"line 1\r\nline 2\n\tline 3\""
}, {
name: "testIgnoreFullTextWhenOpen",
props: {
object: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
fullText: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
member: {open: true},
},
result: "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
}, {
name: "testIgnoreFullTextWithLimit",
props: {
object: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
fullText: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
cropLimit: 20,
},
result: `\"aaaaaaaaa${ELLIPSIS}aaaaaaaa\"`
}, {
name: "testIgnoreFullTextWhenOpenWithLimit",
props: {
object: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
fullText: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
member: {open: true},
cropLimit: 20,
},
result: "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
}];

@@ -77,0 +103,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc