From a6c3da96b059d7a33f677c080cdab8781dd68b0d Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Wed, 3 May 2017 15:59:21 -0400 Subject: [PATCH 1/4] update tests --- src/test/integration/runner.js | 2 +- src/test/integration/tests/tabs.js | 3 ++- src/test/integration/utils/shared.js | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/integration/runner.js b/src/test/integration/runner.js index 58f2759c1d..3614adf083 100644 --- a/src/test/integration/runner.js +++ b/src/test/integration/runner.js @@ -108,7 +108,7 @@ describe("Tests", () => { // expected 2 to equal 1 xit("source maps bogus", async () => await sourceMapsBogus(ctx)); - it("tabs", async () => await tabs(ctx)); + it.only("tabs", async () => await tabs(ctx)); }); mocha.run(); diff --git a/src/test/integration/tests/tabs.js b/src/test/integration/tests/tabs.js index 0242eca65a..0f7e99bd3e 100644 --- a/src/test/integration/tests/tabs.js +++ b/src/test/integration/tests/tabs.js @@ -2,11 +2,12 @@ const { initDebugger, reload, selectSource, + findElement, waitForDispatch } = require("../utils"); function countTabs(dbg) { - return dbg.selectors.getSourceTabs(dbg.getState()).size; + return findElement(dbg, "sourceTabs").children.length; } module.exports = async function(ctx) { diff --git a/src/test/integration/utils/shared.js b/src/test/integration/utils/shared.js index 77aad27d77..cded8922ef 100644 --- a/src/test/integration/utils/shared.js +++ b/src/test/integration/utils/shared.js @@ -28,7 +28,9 @@ const selectors = { sourceFooter: ".source-footer", sourceNode: i => `.sources-list .tree-node:nth-child(${i}) .node`, sourceNodes: ".sources-list .tree-node", - sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow` + sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`, + sourceTab: ``, + sourceTabs: `.source-tabs` }; function findElement(dbg, elementName, ...args) { From f76a1f5b4fc1f881a0a60c8388e4d017aac7680e Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Wed, 3 May 2017 16:24:03 -0400 Subject: [PATCH 2/4] type tabs component --- src/components/Editor/Tabs.js | 62 ++++++++++++++++++++++------------- src/reducers/sources.js | 2 +- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/components/Editor/Tabs.js b/src/components/Editor/Tabs.js index 0514c9391e..a50e0d73e2 100644 --- a/src/components/Editor/Tabs.js +++ b/src/components/Editor/Tabs.js @@ -1,9 +1,10 @@ // @flow -import { DOM as dom, PropTypes, PureComponent, createFactory } from "react"; -import ImPropTypes from "react-immutable-proptypes"; +import { DOM as dom, PropTypes, Component, createFactory } from "react"; import { connect } from "react-redux"; import { bindActionCreators } from "redux"; +import * as I from "immutable"; + import { getSelectedSource, getSourcesForTabs, @@ -25,6 +26,11 @@ const PaneToggleButton = createFactory(_PaneToggleButton); import _Dropdown from "../shared/Dropdown"; const Dropdown = createFactory(_Dropdown); +import type { List } from "immutable"; +import type { Source } from "debugger-html"; +import type { SourceRecord } from "../../reducers/sources"; +type SourcesList = List; + /* * Finds the hidden tabs by comparing the tabs' top offset. * hidden tabs will have a great top offset. @@ -34,7 +40,7 @@ const Dropdown = createFactory(_Dropdown); * * @returns Immutable.list */ -function getHiddenTabs(sourceTabs, sourceTabEls) { +function getHiddenTabs(sourceTabs: SourcesList, sourceTabEls) { sourceTabEls = [].slice.call(sourceTabEls); function getTopOffset() { const topOffsets = sourceTabEls.map(t => t.getBoundingClientRect().top); @@ -66,7 +72,7 @@ function copyToTheClipboard(string) { type State = { dropdownShown: boolean, - hiddenSourceTabs: Array | null + hiddenSourceTabs: SourcesList }; class SourceTabs extends PureComponent { @@ -82,13 +88,29 @@ class SourceTabs extends PureComponent { renderDropDown: Function; renderStartPanelToggleButton: Function; renderEndPanelToggleButton: Function; + + props: { + sourceTabs: SourcesList, + selectedSource: SourceRecord, + selectSource: (string, ?Object) => any, + closeTab: string => any, + closeTabs: List => any, + toggleProjectSearch: () => any, + togglePrettyPrint: string => any, + togglePaneCollapse: () => any, + showSource: string => any, + horizontal: boolean, + startPanelCollapsed: boolean, + endPanelCollapsed: boolean + }; + onResize: Function; constructor(props) { super(props); this.state = { dropdownShown: false, - hiddenSourceTabs: null + hiddenSourceTabs: I.List() }; this.onTabContextMenu = this.onTabContextMenu.bind(this); @@ -127,7 +149,7 @@ class SourceTabs extends PureComponent { window.removeEventListener("resize", this.onResize); } - onTabContextMenu(event, tab) { + onTabContextMenu(event, tab: string) { event.preventDefault(); this.showContextMenu(event, tab); } @@ -166,6 +188,11 @@ class SourceTabs extends PureComponent { const sourceTab = sourceTabs.find(t => t.get("id") == tab); const tabURLs = sourceTabs.map(thisTab => thisTab.get("url")); const otherTabURLs = otherTabs.map(thisTab => thisTab.get("url")); + + if (!sourceTab) { + return; + } + const isPrettySource = isPretty(sourceTab.toJS()); const closeTabMenuItem = { @@ -272,7 +299,7 @@ class SourceTabs extends PureComponent { }); } - renderDropdownSource(source) { + renderDropdownSource(source: SourceRecord) { const { selectSource } = this.props; const filename = getFilename(source.toJS()); @@ -291,13 +318,17 @@ class SourceTabs extends PureComponent { renderTabs() { const sourceTabs = this.props.sourceTabs; + if (!sourceTabs) { + return; + } + return dom.div( { className: "source-tabs", ref: "sourceTabs" }, sourceTabs.map(this.renderTab) ); } - renderTab(source) { + renderTab(source: SourceRecord) { const { selectedSource, selectSource, closeTab } = this.props; const filename = getFilename(source.toJS()); const active = @@ -400,21 +431,6 @@ class SourceTabs extends PureComponent { } } -SourceTabs.propTypes = { - sourceTabs: ImPropTypes.list.isRequired, - selectedSource: ImPropTypes.map, - selectSource: PropTypes.func.isRequired, - closeTab: PropTypes.func.isRequired, - closeTabs: PropTypes.func.isRequired, - toggleProjectSearch: PropTypes.func.isRequired, - togglePrettyPrint: PropTypes.func.isRequired, - togglePaneCollapse: PropTypes.func.isRequired, - showSource: PropTypes.func.isRequired, - horizontal: PropTypes.bool.isRequired, - startPanelCollapsed: PropTypes.bool.isRequired, - endPanelCollapsed: PropTypes.bool.isRequired -}; - SourceTabs.displayName = "SourceTabs"; module.exports = connect( diff --git a/src/reducers/sources.js b/src/reducers/sources.js index 3cdcb060f1..3cfa5ddbc5 100644 --- a/src/reducers/sources.js +++ b/src/reducers/sources.js @@ -19,7 +19,7 @@ import type { Source, Location } from "../types"; import type { Action } from "../actions/types"; import type { Record } from "../utils/makeRecord"; -type SourceRecord = Record; +export type SourceRecord = Record; type SourcesMap = Map; export type SourcesState = { From f7a936a94e457ac5cd01c6e2aea5bcd6d0153c7f Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Wed, 3 May 2017 16:54:07 -0400 Subject: [PATCH 3/4] fixes --- flow-typed/debugger-html.js | 3 ++- src/reducers/sources.js | 32 ++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/flow-typed/debugger-html.js b/flow-typed/debugger-html.js index 3e8e9ef617..f9acdc3391 100644 --- a/flow-typed/debugger-html.js +++ b/flow-typed/debugger-html.js @@ -180,7 +180,8 @@ declare module "debugger-html" { declare type SourceText = { id: string, text: string, - contentType: string + contentType: string, + loading?: boolean }; /** diff --git a/src/reducers/sources.js b/src/reducers/sources.js index 3cfa5ddbc5..c0bb25367a 100644 --- a/src/reducers/sources.js +++ b/src/reducers/sources.js @@ -15,12 +15,16 @@ import { getPrettySourceURL } from "../utils/source"; import { prefs } from "../utils/prefs"; import type { Map, List } from "immutable"; -import type { Source, Location } from "../types"; +import type { Source, SourceText, Location } from "../types"; import type { Action } from "../actions/types"; import type { Record } from "../utils/makeRecord"; +type Tab = string; export type SourceRecord = Record; +export type SourceTextRecord = Record; type SourcesMap = Map; +type SourceTextMap = Map; +type TabList = List; export type SourcesState = { sources: SourcesMap, @@ -35,8 +39,8 @@ export type SourcesState = { column?: number }, selectedLocation?: Location, - sourcesText: Map, - tabs: List + sourcesText: SourceTextMap, + tabs: TabList }; export const State = makeRecord( @@ -256,9 +260,8 @@ function getNewSelectedSourceId(state: SourcesState, availableTabs): string { const leftNeighborIndex = Math.max(tabUrls.indexOf(selectedTabUrl) - 1, 0); const lastAvailbleTabIndex = availableTabs.size - 1; const newSelectedTabIndex = Math.min(leftNeighborIndex, lastAvailbleTabIndex); - let tabSource = state.sources.find( - source => source.get("url") === availableTabs.toJS()[newSelectedTabIndex] - ); + const availableTab = availableTabs.toJS()[newSelectedTabIndex]; + const tabSource = getSourceByUrlInSources(state.sources, availableTab); if (tabSource) { return tabSource.get("id"); @@ -284,11 +287,14 @@ export function getSource(state: OuterState, id: string) { return getSourceInSources(getSources(state), id); } -export function getSourceByURL(state: OuterState, url: string) { +export function getSourceByURL(state: OuterState, url: string): ?SourceRecord { return getSourceByUrlInSources(state.sources.sources, url); } -export function getSourceText(state: OuterState, id: ?string) { +export function getSourceText( + state: OuterState, + id: ?string +): ?SourceTextRecord { if (id) { return state.sources.sourcesText.get(id); } @@ -331,10 +337,12 @@ export const getSourceTabs = createSelector( export const getSourcesForTabs = createSelector( getSourceTabs, getSources, - (tabs, sources) => - tabs - .map(tab => getSourceByUrlInSources(sources, tabs)) - .filter(source => source) + (tabs: TabList, sources: SourcesMap) => { + const newTabs = tabs + .map(tab => getSourceByUrlInSources(sources, tab)) + .filter(source => source); + return newTabs; + } ); export const getSelectedLocation = createSelector( From 347cba42ce764b44057e1975102bae373e037534 Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Wed, 3 May 2017 16:58:41 -0400 Subject: [PATCH 4/4] fixes --- src/components/Editor/Tabs.js | 3 +-- src/reducers/sources.js | 3 +-- src/test/integration/runner.js | 2 +- src/test/integration/utils/shared.js | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/Editor/Tabs.js b/src/components/Editor/Tabs.js index a50e0d73e2..8ee42ffd63 100644 --- a/src/components/Editor/Tabs.js +++ b/src/components/Editor/Tabs.js @@ -1,6 +1,6 @@ // @flow -import { DOM as dom, PropTypes, Component, createFactory } from "react"; +import { DOM as dom, PureComponent, createFactory } from "react"; import { connect } from "react-redux"; import { bindActionCreators } from "redux"; import * as I from "immutable"; @@ -27,7 +27,6 @@ import _Dropdown from "../shared/Dropdown"; const Dropdown = createFactory(_Dropdown); import type { List } from "immutable"; -import type { Source } from "debugger-html"; import type { SourceRecord } from "../../reducers/sources"; type SourcesList = List; diff --git a/src/reducers/sources.js b/src/reducers/sources.js index c0bb25367a..c7fc4379df 100644 --- a/src/reducers/sources.js +++ b/src/reducers/sources.js @@ -338,10 +338,9 @@ export const getSourcesForTabs = createSelector( getSourceTabs, getSources, (tabs: TabList, sources: SourcesMap) => { - const newTabs = tabs + return tabs .map(tab => getSourceByUrlInSources(sources, tab)) .filter(source => source); - return newTabs; } ); diff --git a/src/test/integration/runner.js b/src/test/integration/runner.js index 3614adf083..58f2759c1d 100644 --- a/src/test/integration/runner.js +++ b/src/test/integration/runner.js @@ -108,7 +108,7 @@ describe("Tests", () => { // expected 2 to equal 1 xit("source maps bogus", async () => await sourceMapsBogus(ctx)); - it.only("tabs", async () => await tabs(ctx)); + it("tabs", async () => await tabs(ctx)); }); mocha.run(); diff --git a/src/test/integration/utils/shared.js b/src/test/integration/utils/shared.js index cded8922ef..44bf1ac0be 100644 --- a/src/test/integration/utils/shared.js +++ b/src/test/integration/utils/shared.js @@ -29,7 +29,6 @@ const selectors = { sourceNode: i => `.sources-list .tree-node:nth-child(${i}) .node`, sourceNodes: ".sources-list .tree-node", sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`, - sourceTab: ``, sourceTabs: `.source-tabs` };