Bug 1333364 - Introduce id props to tab r=Honza

MozReview-Commit-ID: 1nbK6mlRSIr

--HG--
extra : rebase_source : 9091d17997c1f0e3e855b50aaaa307434d74f930
This commit is contained in:
Ricky Chien 2017-01-25 00:25:11 +08:00
Родитель 697b81abea
Коммит 10802be454
33 изменённых файлов: 156 добавлений и 335 удалений

Просмотреть файл

@ -48,12 +48,12 @@ function resizeWaterfall(width) {
/** /**
* Change the selected tab for details panel. * Change the selected tab for details panel.
* *
* @param {number} index - tab index to be selected * @param {string} id - tab id to be selected
*/ */
function selectDetailsPanelTab(index) { function selectDetailsPanelTab(id) {
return { return {
type: SELECT_DETAILS_PANEL_TAB, type: SELECT_DETAILS_PANEL_TAB,
index, id,
}; };
} }

Просмотреть файл

@ -264,7 +264,7 @@ module.exports = connect(
const { securityState } = item; const { securityState } = item;
// Choose the security tab. // Choose the security tab.
if (securityState && securityState !== "insecure") { if (securityState && securityState !== "insecure") {
dispatch(Actions.selectDetailsPanelTab(5)); dispatch(Actions.selectDetailsPanelTab("security"));
} }
}, },
}) })

Просмотреть файл

@ -59,15 +59,9 @@ const EVENTS = {
RESPONSE_IMAGE_THUMBNAIL_DISPLAYED: RESPONSE_IMAGE_THUMBNAIL_DISPLAYED:
"NetMonitor:ResponseImageThumbnailAvailable", "NetMonitor:ResponseImageThumbnailAvailable",
// When a tab is selected in the NetworkDetailsView and subsequently rendered.
TAB_UPDATED: "NetMonitor:TabUpdated",
// Fired when Sidebar has finished being populated. // Fired when Sidebar has finished being populated.
SIDEBAR_POPULATED: "NetMonitor:SidebarPopulated", SIDEBAR_POPULATED: "NetMonitor:SidebarPopulated",
// Fired when NetworkDetailsView has finished being populated.
NETWORKDETAILSVIEW_POPULATED: "NetMonitor:NetworkDetailsViewPopulated",
// Fired when CustomRequestView has finished being populated. // Fired when CustomRequestView has finished being populated.
CUSTOMREQUESTVIEW_POPULATED: "NetMonitor:CustomRequestViewPopulated", CUSTOMREQUESTVIEW_POPULATED: "NetMonitor:CustomRequestViewPopulated",

Просмотреть файл

@ -13,7 +13,7 @@ const {
} = require("../constants"); } = require("../constants");
const UI = I.Record({ const UI = I.Record({
detailsPanelSelectedTab: 0, detailsPanelSelectedTab: "headers",
sidebarOpen: false, sidebarOpen: false,
statisticsOpen: false, statisticsOpen: false,
waterfallWidth: null, waterfallWidth: null,
@ -35,7 +35,7 @@ function openStatistics(state, action) {
} }
function setDetailsPanelTab(state, action) { function setDetailsPanelTab(state, action) {
return state.set("detailsPanelSelectedTab", action.index); return state.set("detailsPanelSelectedTab", action.id);
} }
function ui(state = new UI(), action) { function ui(state = new UI(), action) {

Просмотреть файл

@ -38,10 +38,10 @@ const PREVIEW_TITLE = L10N.getStr("netmonitor.tab.preview");
* Display the network request details * Display the network request details
*/ */
function DetailsPanel({ function DetailsPanel({
activeTabId,
cloneSelectedRequest, cloneSelectedRequest,
request, request,
setTabIndex, selectTab,
tabIndex,
toolbox, toolbox,
}) { }) {
if (!request) { if (!request) {
@ -50,9 +50,9 @@ function DetailsPanel({
return ( return (
Tabbar({ Tabbar({
onSelect: setTabIndex, activeTabId,
onSelect: selectTab,
showAllTabsMenu: true, showAllTabsMenu: true,
tabActive: tabIndex,
toolbox, toolbox,
}, },
TabPanel({ TabPanel({
@ -109,17 +109,17 @@ DetailsPanel.propTypes = {
cloneSelectedRequest: PropTypes.func.isRequired, cloneSelectedRequest: PropTypes.func.isRequired,
request: PropTypes.object, request: PropTypes.object,
setTabIndex: PropTypes.func.isRequired, setTabIndex: PropTypes.func.isRequired,
tabIndex: PropTypes.number.isRequired, selectedTab: PropTypes.number.isRequired,
toolbox: PropTypes.object.isRequired, toolbox: PropTypes.object.isRequired,
}; };
module.exports = connect( module.exports = connect(
(state) => ({ (state) => ({
activeTabId: state.ui.detailsPanelSelectedTab,
request: getSelectedRequest(state), request: getSelectedRequest(state),
tabIndex: state.ui.detailsPanelSelectedTab,
}), }),
(dispatch) => ({ (dispatch) => ({
cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()), cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()),
setTabIndex: (index) => dispatch(Actions.selectDetailsPanelTab(index)), selectTab: (tabId) => dispatch(Actions.selectDetailsPanelTab(tabId)),
}), }),
)(DetailsPanel); )(DetailsPanel);

Просмотреть файл

@ -94,8 +94,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
[browser_net_cors_requests.js] [browser_net_cors_requests.js]
[browser_net_cyrillic-01.js] [browser_net_cyrillic-01.js]
[browser_net_cyrillic-02.js] [browser_net_cyrillic-02.js]
[browser_net_details-no-duplicated-content.js]
skip-if = true # Test broken in React version, is too low-level
[browser_net_frame.js] [browser_net_frame.js]
skip-if = (os == 'linux' && debug && bits == 32) # Bug 1321434 skip-if = (os == 'linux' && debug && bits == 32) # Bug 1321434
[browser_net_filter-01.js] [browser_net_filter-01.js]

Просмотреть файл

@ -38,10 +38,10 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3 .editor-mount iframe"); wait = waitForDOM(document, "#response-panel .editor-mount iframe");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
let [editorFrame] = yield wait; let [editorFrame] = yield wait;
yield once(editorFrame, "DOMContentLoaded"); yield once(editorFrame, "DOMContentLoaded");

Просмотреть файл

@ -25,43 +25,43 @@ add_task(function* () {
}); });
yield wait; yield wait;
wait = waitForDOM(document, "#panel-2 .tree-section", 2); wait = waitForDOM(document, "#params-panel .tree-section", 2);
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
testParamsTab1("a", '""', '{ "foo": "bar" }', '""'); testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
wait = waitForDOM(document, "#panel-2 .tree-section", 2); wait = waitForDOM(document, "#params-panel .tree-section", 2);
RequestsMenu.selectedIndex = 1; RequestsMenu.selectedIndex = 1;
yield wait; yield wait;
testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""'); testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
wait = waitForDOM(document, "#panel-2 .tree-section", 2); wait = waitForDOM(document, "#params-panel .tree-section", 2);
RequestsMenu.selectedIndex = 2; RequestsMenu.selectedIndex = 2;
yield wait; yield wait;
testParamsTab1("a", '"b"', "foo", '"bar"'); testParamsTab1("a", '"b"', "foo", '"bar"');
wait = waitForDOM(document, "#panel-2 tr:not(.tree-section).treeRow", 2); wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
RequestsMenu.selectedIndex = 3; RequestsMenu.selectedIndex = 3;
yield wait; yield wait;
testParamsTab2("a", '""', '{ "foo": "bar" }', "js"); testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
wait = waitForDOM(document, "#panel-2 tr:not(.tree-section).treeRow", 2); wait = waitForDOM(document, "#params-panel tr:not(.tree-section).treeRow", 2);
RequestsMenu.selectedIndex = 4; RequestsMenu.selectedIndex = 4;
yield wait; yield wait;
testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js"); testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
// Wait for all tree sections and editor updated by react // Wait for all tree sections and editor updated by react
let waitSections = waitForDOM(document, "#panel-2 .tree-section", 2); let waitSections = waitForDOM(document, "#params-panel .tree-section", 2);
let waitEditor = waitForDOM(document, "#panel-2 .editor-mount iframe"); let waitEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
RequestsMenu.selectedIndex = 5; RequestsMenu.selectedIndex = 5;
let [, editorFrames] = yield Promise.all([waitSections, waitEditor]); let [, editorFrames] = yield Promise.all([waitSections, waitEditor]);
yield once(editorFrames[0], "DOMContentLoaded"); yield once(editorFrames[0], "DOMContentLoaded");
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code"); yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
testParamsTab2("a", '"b"', "?foo=bar", "text"); testParamsTab2("a", '"b"', "?foo=bar", "text");
wait = waitForDOM(document, "#panel-2 .empty-notice"); wait = waitForDOM(document, "#params-panel .empty-notice");
RequestsMenu.selectedIndex = 6; RequestsMenu.selectedIndex = 6;
yield wait; yield wait;
testParamsTab3(); testParamsTab3();
@ -70,7 +70,7 @@ add_task(function* () {
function testParamsTab1(queryStringParamName, queryStringParamValue, function testParamsTab1(queryStringParamName, queryStringParamValue,
formDataParamName, formDataParamValue) { formDataParamName, formDataParamValue) {
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
is(tabpanel.querySelectorAll(".tree-section").length, 2, is(tabpanel.querySelectorAll(".tree-section").length, 2,
"The number of param tree sections displayed in this tabpanel is incorrect."); "The number of param tree sections displayed in this tabpanel is incorrect.");
@ -111,7 +111,7 @@ add_task(function* () {
function testParamsTab2(queryStringParamName, queryStringParamValue, function testParamsTab2(queryStringParamName, queryStringParamValue,
requestPayload, editorMode) { requestPayload, editorMode) {
let isJSON = editorMode === "js"; let isJSON = editorMode === "js";
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
is(tabpanel.querySelectorAll(".tree-section").length, 2, is(tabpanel.querySelectorAll(".tree-section").length, 2,
"The number of param tree sections displayed in this tabpanel is incorrect."); "The number of param tree sections displayed in this tabpanel is incorrect.");
@ -164,7 +164,7 @@ add_task(function* () {
} }
function testParamsTab3() { function testParamsTab3() {
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
is(tabpanel.querySelectorAll(".tree-section").length, 0, is(tabpanel.querySelectorAll(".tree-section").length, 0,
"The number of param tree sections displayed in this tabpanel is incorrect."); "The number of param tree sections displayed in this tabpanel is incorrect.");

Просмотреть файл

@ -90,14 +90,6 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click();
yield wait;
RequestsMenu.selectedIndex = -1;
yield selectIndexAndWaitForEditor(0); yield selectIndexAndWaitForEditor(0);
yield testResponseTab("xml"); yield testResponseTab("xml");
@ -122,7 +114,7 @@ add_task(function* () {
yield teardown(monitor); yield teardown(monitor);
function* testResponseTab(type) { function* testResponseTab(type) {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
function checkVisibility(box) { function checkVisibility(box) {
is(tabpanel.querySelector(".response-error-header") === null, is(tabpanel.querySelector(".response-error-header") === null,
@ -232,10 +224,11 @@ add_task(function* () {
} }
function* selectIndexAndWaitForEditor(index) { function* selectIndexAndWaitForEditor(index) {
let editor = document.querySelector("#panel-3 .editor-mount iframe"); let editor = document.querySelector("#response-panel .editor-mount iframe");
if (!editor) { if (!editor) {
let waitDOM = waitForDOM(document, ".editor-mount iframe"); let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
RequestsMenu.selectedIndex = index; RequestsMenu.selectedIndex = index;
document.querySelector("#response-tab").click();
[editor] = yield waitDOM; [editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
} else { } else {
@ -246,14 +239,14 @@ add_task(function* () {
} }
function* selectIndexAndWaitForJSONView(index) { function* selectIndexAndWaitForJSONView(index) {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".treeTable"); let waitDOM = waitForDOM(tabpanel, ".treeTable");
RequestsMenu.selectedIndex = index; RequestsMenu.selectedIndex = index;
yield waitDOM; yield waitDOM;
} }
function* selectIndexAndWaitForImageView(index) { function* selectIndexAndWaitForImageView(index) {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
let waitDOM = waitForDOM(tabpanel, ".response-image"); let waitDOM = waitForDOM(tabpanel, ".response-image");
RequestsMenu.selectedIndex = index; RequestsMenu.selectedIndex = index;
let [imageNode] = yield waitDOM; let [imageNode] = yield waitDOM;

Просмотреть файл

@ -28,10 +28,10 @@ add_task(function* () {
statusText: "DA DA DA" statusText: "DA DA DA"
}); });
wait = waitForDOM(document, "#panel-3 .editor-mount iframe"); wait = waitForDOM(document, "#response-panel .editor-mount iframe");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
let [editor] = yield wait; let [editor] = yield wait;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code"); yield waitForDOM(editor.contentDocument, ".CodeMirror-code");

Просмотреть файл

@ -27,10 +27,10 @@ add_task(function* () {
statusText: "OK" statusText: "OK"
}); });
wait = waitForDOM(document, "#panel-3 .editor-mount iframe"); wait = waitForDOM(document, "#response-panel .editor-mount iframe");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
let [editor] = yield wait; let [editor] = yield wait;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code"); yield waitForDOM(editor.contentDocument, ".CodeMirror-code");

Просмотреть файл

@ -1,171 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// A test to ensure that the content in details pane is not duplicated.
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CUSTOM_GET_URL);
let panel = monitor.panelWin;
let { NetMonitorView, EVENTS } = panel;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
const COOKIE_UNIQUE_PATH = "/do-not-use-in-other-tests-using-cookies";
let TEST_CASES = [
{
desc: "Test headers tab",
pageURI: CUSTOM_GET_URL,
requestURI: null,
isPost: false,
tabIndex: 0,
variablesView: NetworkDetails._headers,
expectedScopeLength: 2,
},
{
desc: "Test cookies tab",
pageURI: CUSTOM_GET_URL,
requestURI: COOKIE_UNIQUE_PATH,
isPost: false,
tabIndex: 1,
variablesView: NetworkDetails._cookies,
expectedScopeLength: 1,
},
{
desc: "Test params tab",
pageURI: POST_RAW_URL,
requestURI: null,
isPost: true,
tabIndex: 2,
variablesView: NetworkDetails._params,
expectedScopeLength: 1,
},
];
info("Adding a cookie for the \"Cookie\" tab test");
yield setDocCookie("a=b; path=" + COOKIE_UNIQUE_PATH);
info("Running tests");
for (let spec of TEST_CASES) {
yield runTestCase(spec);
}
// Remove the cookie. If an error occurs the path of the cookie ensures it
// doesn't mess with the other tests.
info("Removing the added cookie.");
yield setDocCookie(
"a=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=" + COOKIE_UNIQUE_PATH);
yield teardown(monitor);
/**
* Set a content document cookie
*/
function setDocCookie(cookie) {
return ContentTask.spawn(tab.linkedBrowser, cookie, function* (cookieArg) {
content.document.cookie = cookieArg;
});
}
/**
* A helper that handles the execution of each case.
*/
function* runTestCase(spec) {
info("Running case: " + spec.desc);
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.loadURI(spec.pageURI);
yield wait;
RequestsMenu.clear();
yield waitForFinalDetailTabUpdate(spec.tabIndex, spec.isPost, spec.requestURI);
is(spec.variablesView._store.length, spec.expectedScopeLength,
"View contains " + spec.expectedScopeLength + " scope headers");
}
/**
* A helper that prepares the variables view for the actual testing. It
* - selects the correct tab
* - performs the specified request to specified URI
* - opens the details view
* - waits for the final update to happen
*/
function* waitForFinalDetailTabUpdate(tabIndex, isPost, uri) {
let onNetworkEvent = panel.once(EVENTS.NETWORK_EVENT);
let onDetailsPopulated = panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
let onRequestFinished = isPost ?
waitForNetworkEvents(monitor, 0, 1) :
waitForNetworkEvents(monitor, 1);
info("Performing a request");
yield ContentTask.spawn(tab.linkedBrowser, uri, function* (url) {
content.wrappedJSObject.performRequests(1, url);
});
info("Waiting for NETWORK_EVENT");
yield onNetworkEvent;
if (!RequestsMenu.getItemAtIndex(0)) {
info("Waiting for the request to be added to the view");
yield monitor.panelWin.once(EVENTS.REQUEST_ADDED);
}
ok(true, "Received NETWORK_EVENT. Selecting the item.");
let item = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = item;
info("Item selected. Waiting for NETWORKDETAILSVIEW_POPULATED");
yield onDetailsPopulated;
info("Received populated event. Selecting tab at index " + tabIndex);
NetworkDetails.widget.selectedIndex = tabIndex;
info("Waiting for request to finish.");
yield onRequestFinished;
ok(true, "Request finished.");
/**
* Because this test uses lazy updates there's four scenarios to consider:
* #1: Everything is updated and test is ready to continue.
* #2: There's updates that are waiting to be flushed.
* #3: Updates are flushed but the tab update is still running.
* #4: There's pending updates and a tab update is still running.
*
* For case #1 there's not going to be a TAB_UPDATED event so don't wait for
* it (bug 1106181).
*
* For cases #2 and #3 it's enough to wait for one TAB_UPDATED event as for
* - case #2 the next flush will perform the final update and single
* TAB_UPDATED event is emitted.
* - case #3 the running update is the final update that'll emit one
* TAB_UPDATED event.
*
* For case #4 we must wait for the updates to be flushed before we can
* start waiting for TAB_UPDATED event or we'll continue the test right
* after the pending update finishes.
*/
let hasQueuedUpdates = RequestsMenu._updateQueue.length !== 0;
let hasRunningTabUpdate = NetworkDetails._viewState.updating[tabIndex];
if (hasQueuedUpdates || hasRunningTabUpdate) {
info("There's pending updates - waiting for them to finish.");
info(" hasQueuedUpdates: " + hasQueuedUpdates);
info(" hasRunningTabUpdate: " + hasRunningTabUpdate);
if (hasQueuedUpdates && hasRunningTabUpdate) {
info("Waiting for updates to be flushed.");
// _flushRequests calls .populate which emits the following event
yield panel.once(EVENTS.NETWORKDETAILSVIEW_POPULATED);
info("Requests flushed.");
}
info("Waiting for final tab update.");
yield waitFor(panel, EVENTS.TAB_UPDATED);
}
info("All updates completed.");
}
});

Просмотреть файл

@ -25,26 +25,26 @@ add_task(function* () {
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
ok(document.querySelector("#tab-0.is-active"), ok(document.querySelector("#headers-tab[aria-selected=true]"),
"The headers tab in the details panel should be selected."); "The headers tab in the details panel should be selected.");
ok(!document.querySelector("#tab-5"), ok(!document.querySelector("#preview-tab"),
"The preview tab should be hidden for non html responses."); "The preview tab should be hidden for non html responses.");
ok(!document.querySelector("#panel-5"), ok(!document.querySelector("#preview-panel"),
"The preview panel is hidden for non html responses."); "The preview panel is hidden for non html responses.");
wait = waitForDOM(document, "#tab-5"); wait = waitForDOM(document, ".tabs");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[4]); document.querySelectorAll(".request-list-item")[4]);
yield wait; yield wait;
document.querySelector("#tab-5 a").click(); document.querySelector("#preview-tab").click();
ok(document.querySelector("#tab-5.is-active"), ok(document.querySelector("#preview-tab[aria-selected=true]"),
"The preview tab in the details panel should be selected."); "The preview tab in the details panel should be selected.");
ok(document.querySelector("#panel-5"), ok(document.querySelector("#preview-panel"),
"The preview panel should be visible now."); "The preview panel should be visible now.");
let iframe = document.querySelector("#panel-5 iframe"); let iframe = document.querySelector("#preview-panel iframe");
yield once(iframe, "DOMContentLoaded"); yield once(iframe, "DOMContentLoaded");
ok(iframe, ok(iframe,
@ -57,11 +57,11 @@ add_task(function* () {
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[5]); document.querySelectorAll(".request-list-item")[5]);
ok(document.querySelector("#tab-0.is-active"), ok(document.querySelector("#headers-tab[aria-selected=true]"),
"The headers tab in the details panel should be selected again."); "The headers tab in the details panel should be selected again.");
ok(!document.querySelector("#tab-5"), ok(!document.querySelector("#preview-tab"),
"The preview tab should be hidden again for non html responses."); "The preview tab should be hidden again for non html responses.");
ok(!document.querySelector("#panel-5"), ok(!document.querySelector("#preview-panel"),
"The preview panel is hidden again for non html responses."); "The preview panel is hidden again for non html responses.");
yield teardown(monitor); yield teardown(monitor);

Просмотреть файл

@ -39,10 +39,10 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3"); wait = waitForDOM(document, "#response-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
yield wait; yield wait;
testResponseTab(); testResponseTab();
@ -50,7 +50,7 @@ add_task(function* () {
yield teardown(monitor); yield teardown(monitor);
function testResponseTab() { function testResponseTab() {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, true, is(tabpanel.querySelector(".response-error-header") === null, true,
"The response error header doesn't have the intended visibility."); "The response error header doesn't have the intended visibility.");

Просмотреть файл

@ -31,15 +31,15 @@ add_task(function* () {
fullMimeType: "text/json; charset=utf-8" fullMimeType: "text/json; charset=utf-8"
}); });
wait = waitForDOM(document, "#panel-3 .editor-mount iframe"); wait = waitForDOM(document, "#response-panel .editor-mount iframe");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
let [editor] = yield wait; let [editor] = yield wait;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code"); yield waitForDOM(editor.contentDocument, ".CodeMirror-code");
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, false, is(tabpanel.querySelector(".response-error-header") === null, false,
"The response error header doesn't have the intended visibility."); "The response error header doesn't have the intended visibility.");
is(tabpanel.querySelector(".response-error-header").textContent, is(tabpanel.querySelector(".response-error-header").textContent,

Просмотреть файл

@ -34,10 +34,10 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3"); wait = waitForDOM(document, "#response-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
yield wait; yield wait;
testResponseTab(); testResponseTab();
@ -45,7 +45,7 @@ add_task(function* () {
yield teardown(monitor); yield teardown(monitor);
function testResponseTab() { function testResponseTab() {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, true, is(tabpanel.querySelector(".response-error-header") === null, true,
"The response error header doesn't have the intended visibility."); "The response error header doesn't have the intended visibility.");

Просмотреть файл

@ -34,10 +34,10 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3"); wait = waitForDOM(document, "#response-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
yield wait; yield wait;
testResponseTab(); testResponseTab();
@ -45,7 +45,7 @@ add_task(function* () {
yield teardown(monitor); yield teardown(monitor);
function testResponseTab() { function testResponseTab() {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, true, is(tabpanel.querySelector(".response-error-header") === null, true,
"The response error header doesn't have the intended visibility."); "The response error header doesn't have the intended visibility.");

Просмотреть файл

@ -43,15 +43,15 @@ add_task(function* () {
time: true time: true
}); });
wait = waitForDOM(document, "#panel-3"); wait = waitForDOM(document, "#response-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
yield wait; yield wait;
testResponseTab("$_0123Fun", "\"Hello JSONP!\""); testResponseTab("$_0123Fun", "\"Hello JSONP!\"");
wait = waitForDOM(document, "#panel-3 .tree-section"); wait = waitForDOM(document, "#response-panel .tree-section");
RequestsMenu.selectedIndex = 1; RequestsMenu.selectedIndex = 1;
yield wait; yield wait;
@ -60,7 +60,7 @@ add_task(function* () {
yield teardown(monitor); yield teardown(monitor);
function testResponseTab(func, greeting) { function testResponseTab(func, greeting) {
let tabpanel = document.querySelector("#panel-3"); let tabpanel = document.querySelector("#response-panel");
is(tabpanel.querySelector(".response-error-header") === null, true, is(tabpanel.querySelector(".response-error-header") === null, true,
"The response error header doesn't have the intended visibility."); "The response error header doesn't have the intended visibility.");

Просмотреть файл

@ -34,10 +34,10 @@ add_task(function* () {
statusText: "OK" statusText: "OK"
}); });
let waitDOM = waitForDOM(document, "#panel-3 .editor-mount iframe"); let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
let [editor] = yield waitDOM; let [editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
yield waitForDOM(editor.contentDocument, ".CodeMirror-code"); yield waitForDOM(editor.contentDocument, ".CodeMirror-code");

Просмотреть файл

@ -47,16 +47,16 @@ add_task(function* () {
}); });
// Wait for all tree sections updated by react // Wait for all tree sections updated by react
wait = waitForDOM(document, "#panel-2 .tree-section", 2); wait = waitForDOM(document, "#params-panel .tree-section", 2);
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
yield testParamsTab("urlencoded"); yield testParamsTab("urlencoded");
// Wait for all tree sections and editor updated by react // Wait for all tree sections and editor updated by react
let waitForSections = waitForDOM(document, "#panel-2 .tree-section", 2); let waitForSections = waitForDOM(document, "#params-panel .tree-section", 2);
let waitForEditor = waitForDOM(document, "#panel-2 .editor-mount iframe"); let waitForEditor = waitForDOM(document, "#params-panel .editor-mount iframe");
RequestsMenu.selectedIndex = 1; RequestsMenu.selectedIndex = 1;
let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]); let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]);
yield once(editorFrames[0], "DOMContentLoaded"); yield once(editorFrames[0], "DOMContentLoaded");
@ -66,7 +66,7 @@ add_task(function* () {
return teardown(monitor); return teardown(monitor);
function* testParamsTab(type) { function* testParamsTab(type) {
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
function checkVisibility(box) { function checkVisibility(box) {
is(!tabpanel.querySelector(".treeTable"), !box.includes("params"), is(!tabpanel.querySelector(".treeTable"), !box.includes("params"),

Просмотреть файл

@ -26,13 +26,13 @@ add_task(function* () {
yield wait; yield wait;
// Wait for all tree view updated by react // Wait for all tree view updated by react
wait = waitForDOM(document, "#panel-2 .tree-section"); wait = waitForDOM(document, "#params-panel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"), ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility."); "The request params doesn't have the indended visibility.");

Просмотреть файл

@ -26,13 +26,13 @@ add_task(function* () {
yield wait; yield wait;
// Wait for all tree view updated by react // Wait for all tree view updated by react
wait = waitForDOM(document, "#panel-0"); wait = waitForDOM(document, "#headers-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-0 a").click(); document.querySelector("#headers-tab").click();
yield wait; yield wait;
let tabpanel = document.querySelector("#panel-0"); let tabpanel = document.querySelector("#headers-panel");
is(tabpanel.querySelectorAll(".tree-section .treeLabel").length, 3, is(tabpanel.querySelectorAll(".tree-section .treeLabel").length, 3,
"There should be 3 header sections displayed in this tabpanel."); "There should be 3 header sections displayed in this tabpanel.");
@ -57,11 +57,11 @@ add_task(function* () {
"The second request header value was incorrect."); "The second request header value was incorrect.");
// Wait for all tree sections updated by react // Wait for all tree sections updated by react
wait = waitForDOM(document, "#panel-2 .tree-section"); wait = waitForDOM(document, "#params-panel .tree-section");
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
tabpanel = document.querySelector("#panel-2"); tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"), ok(tabpanel.querySelector(".treeTable"),
"The params tree view should be displayed."); "The params tree view should be displayed.");

Просмотреть файл

@ -26,13 +26,13 @@ add_task(function* () {
yield wait; yield wait;
// Wait for all tree view updated by react // Wait for all tree view updated by react
wait = waitForDOM(document, "#panel-2 .tree-section"); wait = waitForDOM(document, "#params-panel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
let tabpanel = document.querySelector("#panel-2"); let tabpanel = document.querySelector("#params-panel");
ok(tabpanel.querySelector(".treeTable"), ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility."); "The request params doesn't have the indended visibility.");

Просмотреть файл

@ -22,13 +22,13 @@ add_task(function* () {
}); });
yield wait; yield wait;
wait = waitForDOM(document, "#panel-5"); wait = waitForDOM(document, "#security-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelector("#details-pane-toggle")); document.querySelector("#details-pane-toggle"));
document.querySelector("#tab-5 a").click(); document.querySelector("#security-tab").click();
yield wait; yield wait;
let tabpanel = document.querySelector("#panel-5"); let tabpanel = document.querySelector("#security-panel");
let textboxes = tabpanel.querySelectorAll(".textbox-input"); let textboxes = tabpanel.querySelectorAll(".textbox-input");
// Connection // Connection

Просмотреть файл

@ -21,10 +21,10 @@ add_task(function* () {
}); });
yield wait; yield wait;
wait = waitForDOM(document, "#panel-5"); wait = waitForDOM(document, "#security-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelector("#details-pane-toggle")); document.querySelector("#details-pane-toggle"));
document.querySelector("#tab-5 a").click(); document.querySelector("#security-tab").click();
yield wait; yield wait;
let errormsg = document.querySelector(".security-info-value"); let errormsg = document.querySelector(".security-info-value");

Просмотреть файл

@ -24,7 +24,7 @@ add_task(function* () {
info("Selecting headers panel again."); info("Selecting headers panel again.");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelector("#tab-0 a")); document.querySelector("#headers-tab"));
info("Sorting the items by filename."); info("Sorting the items by filename.");
EventUtils.sendMouseEvent({ type: "click" }, EventUtils.sendMouseEvent({ type: "click" },
@ -47,10 +47,11 @@ add_task(function* () {
let item = RequestsMenu.getItemAtIndex(0); let item = RequestsMenu.getItemAtIndex(0);
let icon = document.querySelector(".requests-security-state-icon"); let icon = document.querySelector(".requests-security-state-icon");
let wait = waitForDOM(document, "#panel-5"); let wait = waitForDOM(document, "#security-panel");
info("Clicking security icon of the first request and waiting for panel update."); info("Clicking security icon of the first request and waiting for panel update.");
EventUtils.synthesizeMouseAtCenter(icon, {}, monitor.panelWin); EventUtils.synthesizeMouseAtCenter(icon, {}, monitor.panelWin);
yield wait; yield wait;
ok(document.querySelector("#tab-5.is-active"), "Security tab is selected.");
ok(document.querySelector("#security-tab[aria-selected=true]"), "Security tab is selected.");
} }
}); });

Просмотреть файл

@ -36,13 +36,13 @@ add_task(function* () {
info("Selecting security tab."); info("Selecting security tab.");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelector("#tab-5 a")); document.querySelector("#security-tab"));
info("Selecting insecure request."); info("Selecting insecure request.");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[1]); document.querySelectorAll(".request-list-item")[1]);
ok(document.querySelector("#tab-0.is-active"), ok(document.querySelector("#headers-tab[aria-selected=true]"),
"Selected tab was reset when selected security tab was hidden."); "Selected tab was reset when selected security tab was hidden.");
return teardown(monitor); return teardown(monitor);

Просмотреть файл

@ -58,10 +58,10 @@ add_task(function* () {
is(RequestsMenu.selectedItem.securityState, undefined, is(RequestsMenu.selectedItem.securityState, undefined,
"Security state has not yet arrived."); "Security state has not yet arrived.");
is(!!document.querySelector("#tab-5"), testcase.visibleOnNewEvent, is(!!document.querySelector("#security-tab"), testcase.visibleOnNewEvent,
"Security tab is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") + "Security tab is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
" after new request was added to the menu."); " after new request was added to the menu.");
is(!!document.querySelector("#panel-5"), testcase.visibleOnNewEvent, is(!!document.querySelector("#security-panel"), testcase.visibleOnNewEvent,
"Security panel is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") + "Security panel is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
" after new request was added to the menu."); " after new request was added to the menu.");
@ -70,20 +70,20 @@ add_task(function* () {
ok(RequestsMenu.selectedItem.securityState, ok(RequestsMenu.selectedItem.securityState,
"Security state arrived."); "Security state arrived.");
is(!!document.querySelector("#tab-5"), testcase.visibleOnSecurityInfo, is(!!document.querySelector("#security-tab"), testcase.visibleOnSecurityInfo,
"Security tab is " + (testcase.visibleOnSecurityInfo ? "visible" : "hidden") + "Security tab is " + (testcase.visibleOnSecurityInfo ? "visible" : "hidden") +
" after security information arrived."); " after security information arrived.");
is(!!document.querySelector("#panel-5"), testcase.visibleOnSecurityInfo, is(!!document.querySelector("#security-panel"), testcase.visibleOnSecurityInfo,
"Security panel is " + (testcase.visibleOnSecurityInfo? "visible" : "hidden") + "Security panel is " + (testcase.visibleOnSecurityInfo? "visible" : "hidden") +
" after security information arrived."); " after security information arrived.");
info("Waiting for request to complete."); info("Waiting for request to complete.");
yield onComplete; yield onComplete;
is(!!document.querySelector("#tab-5"), testcase.visibleOnceComplete, is(!!document.querySelector("#security-tab"), testcase.visibleOnceComplete,
"Security tab is " + (testcase.visibleOnceComplete ? "visible" : "hidden") + "Security tab is " + (testcase.visibleOnceComplete ? "visible" : "hidden") +
" after request has been completed."); " after request has been completed.");
is(!!document.querySelector("#panel-5"), testcase.visibleOnceComplete, is(!!document.querySelector("#security-panel"), testcase.visibleOnceComplete,
"Security panel is " + (testcase.visibleOnceComplete? "visible" : "hidden") + "Security panel is " + (testcase.visibleOnceComplete? "visible" : "hidden") +
" after request has been completed."); " after request has been completed.");

Просмотреть файл

@ -38,10 +38,10 @@ add_task(function* () {
document.querySelectorAll(".request-list-item")[0]); document.querySelectorAll(".request-list-item")[0]);
yield wait; yield wait;
if (!document.querySelector("#tab-5.is-active")) { if (!document.querySelector("#security-tab[aria-selected=true]")) {
info("Selecting security tab."); info("Selecting security tab.");
wait = waitForDOM(document, "#panel-5 .properties-view"); wait = waitForDOM(document, "#security-panel .properties-view");
document.querySelector("#tab-5 a").click(); document.querySelector("#security-tab").click();
yield wait; yield wait;
} }

Просмотреть файл

@ -145,12 +145,12 @@ add_task(function* () {
* A function that tests "Headers" panel contains correct information. * A function that tests "Headers" panel contains correct information.
*/ */
function* testHeaders(data, index) { function* testHeaders(data, index) {
let wait = waitForDOM(document, "#panel-0"); let wait = waitForDOM(document, "#headers-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]); document.querySelectorAll(".request-list-item")[index]);
yield wait; yield wait;
let panel = document.querySelector("#panel-0"); let panel = document.querySelector("#headers-panel");
let summaryValues = panel.querySelectorAll(".tabpanel-summary-value.textbox-input"); let summaryValues = panel.querySelectorAll(".tabpanel-summary-value.textbox-input");
let { method, uri, details: { status, statusText } } = data; let { method, uri, details: { status, statusText } } = data;
@ -166,13 +166,13 @@ add_task(function* () {
* A function that tests "Params" panel contains correct information. * A function that tests "Params" panel contains correct information.
*/ */
function* testParams(data, index) { function* testParams(data, index) {
let wait = waitForDOM(document, "#panel-2 .properties-view"); let wait = waitForDOM(document, "#params-panel .properties-view");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll(".request-list-item")[index]); document.querySelectorAll(".request-list-item")[index]);
document.querySelector("#tab-2 a").click(); document.querySelector("#params-tab").click();
yield wait; yield wait;
let panel = document.querySelector("#panel-2"); let panel = document.querySelector("#params-panel");
let statusParamValue = data.uri.split("=").pop(); let statusParamValue = data.uri.split("=").pop();
let statusParamShownValue = "\"" + statusParamValue + "\""; let statusParamShownValue = "\"" + statusParamValue + "\"";
let treeSections = panel.querySelectorAll(".tree-section"); let treeSections = panel.querySelectorAll(".tree-section");

Просмотреть файл

@ -40,10 +40,10 @@ add_task(function* () {
}); });
}); });
wait = waitForDOM(document, "#panel-3"); wait = waitForDOM(document, "#response-panel");
EventUtils.sendMouseEvent({ type: "mousedown" }, EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle")); document.getElementById("details-pane-toggle"));
document.querySelector("#tab-3 a").click(); document.querySelector("#response-tab").click();
yield wait; yield wait;
RequestsMenu.selectedIndex = -1; RequestsMenu.selectedIndex = -1;
@ -59,10 +59,11 @@ add_task(function* () {
return teardown(monitor); return teardown(monitor);
function* selectIndexAndWaitForEditor(index) { function* selectIndexAndWaitForEditor(index) {
let editor = document.querySelector("#panel-3 .editor-mount iframe"); let editor = document.querySelector("#response-panel .editor-mount iframe");
if (!editor) { if (!editor) {
let waitDOM = waitForDOM(document, "#panel-3 .editor-mount iframe"); let waitDOM = waitForDOM(document, "#response-panel .editor-mount iframe");
RequestsMenu.selectedIndex = index; RequestsMenu.selectedIndex = index;
document.querySelector("#response-tab").click();
[editor] = yield waitDOM; [editor] = yield waitDOM;
yield once(editor, "DOMContentLoaded"); yield once(editor, "DOMContentLoaded");
} else { } else {
@ -73,7 +74,7 @@ add_task(function* () {
} }
function testEditorContent([ fmt, textRe ]) { function testEditorContent([ fmt, textRe ]) {
let editor = document.querySelector("#panel-3 .editor-mount iframe"); let editor = document.querySelector("#response-panel .editor-mount iframe");
let text = editor.contentDocument let text = editor.contentDocument
.querySelector(".CodeMirror-line").textContent; .querySelector(".CodeMirror-line").textContent;

Просмотреть файл

@ -25,30 +25,38 @@ let Tabbar = createClass({
children: PropTypes.object, children: PropTypes.object,
onSelect: PropTypes.func, onSelect: PropTypes.func,
showAllTabsMenu: PropTypes.bool, showAllTabsMenu: PropTypes.bool,
tabActive: PropTypes.number, activeTabId: PropTypes.string,
toolbox: PropTypes.object, toolbox: PropTypes.object,
}, },
getDefaultProps: function () { getDefaultProps: function () {
return { return {
showAllTabsMenu: false, showAllTabsMenu: false,
tabActive: 0,
}; };
}, },
getInitialState: function () { getInitialState: function () {
let { children } = this.props; let { activeTabId, children = [] } = this.props;
let tabs = this.createTabs(children);
let activeTab = tabs.findIndex((tab, index) => tab.id === activeTabId);
return { return {
tabs: children ? this.createTabs(children) : [], activeTab: activeTab === -1 ? 0 : activeTab,
activeTab: 0 tabs,
}; };
}, },
componentWillReceiveProps: function (nextProps) { componentWillReceiveProps: function (nextProps) {
let { children } = nextProps; let { activeTabId, children = [] } = nextProps;
let tabs = this.createTabs(children);
let activeTab = tabs.findIndex((tab, index) => tab.id === activeTabId);
if (children && children !== this.props.children) { if (activeTab !== this.state.activeTab ||
this.setState({ tabs: this.createTabs(children) }); (children !== this.props.children)) {
this.setState({
activeTab: activeTab === -1 ? 0 : activeTab,
tabs,
});
} }
}, },
@ -57,7 +65,7 @@ let Tabbar = createClass({
.filter((panel) => panel) .filter((panel) => panel)
.map((panel, index) => .map((panel, index) =>
Object.assign({}, children[index], { Object.assign({}, children[index], {
id: index, id: panel.props.id || index,
panel, panel,
title: panel.props.title, title: panel.props.title,
}) })
@ -137,7 +145,7 @@ let Tabbar = createClass({
getTabIndex: function (tabId) { getTabIndex: function (tabId) {
let tabIndex = -1; let tabIndex = -1;
this.state.tabs.forEach((tab, index) => { this.state.tabs.forEach((tab, index) => {
if (tab.id == tabId) { if (tab.id === tabId) {
tabIndex = index; tabIndex = index;
} }
}); });
@ -214,7 +222,7 @@ let Tabbar = createClass({
Tabs({ Tabs({
onAllTabsMenuClick: this.onAllTabsMenuClick, onAllTabsMenuClick: this.onAllTabsMenuClick,
showAllTabsMenu: this.props.showAllTabsMenu, showAllTabsMenu: this.props.showAllTabsMenu,
tabActive: this.props.tabActive || this.state.activeTab, tabActive: this.state.activeTab,
onAfterChange: this.onTabChanged, onAfterChange: this.onTabChanged,
}, },
tabs tabs

Просмотреть файл

@ -105,8 +105,9 @@ define(function (require, exports, module) {
if (typeof tabActive === "number") { if (typeof tabActive === "number") {
let panels = children.filter((panel) => panel); let panels = children.filter((panel) => panel);
// Reset to index 0 if index larger than number of panels // Reset to index 0 if index overflows the range of panel array
tabActive = tabActive < panels.length ? tabActive : 0; tabActive = (tabActive < panels.length && tabActive >= 0) ?
tabActive : 0;
let created = [...this.state.created]; let created = [...this.state.created];
created[tabActive] = true; created[tabActive] = true;
@ -224,17 +225,16 @@ define(function (require, exports, module) {
} }
let tabs = this.props.children let tabs = this.props.children
.map(tab => { .map((tab) => typeof tab === "function" ? tab() : tab)
return typeof tab === "function" ? tab() : tab; .filter((tab) => tab)
}).filter(tab => { .map((tab, index) => {
return tab; let id = tab.props.id;
}).map((tab, index) => { let ref = "tab-menu-" + index;
let ref = ("tab-menu-" + index);
let title = tab.props.title; let title = tab.props.title;
let tabClassName = tab.props.className; let tabClassName = tab.props.className;
let isTabSelected = this.state.tabActive === index; let isTabSelected = this.state.tabActive === index;
let classes = [ let className = [
"tabs-menu-item", "tabs-menu-item",
tabClassName, tabClassName,
isTabSelected ? "is-active" : "" isTabSelected ? "is-active" : ""
@ -247,15 +247,15 @@ define(function (require, exports, module) {
// See also `onKeyDown()` event handler. // See also `onKeyDown()` event handler.
return ( return (
DOM.li({ DOM.li({
ref: ref, className,
key: index, key: index,
id: "tab-" + index, ref,
className: classes,
role: "presentation", role: "presentation",
}, },
DOM.a({ DOM.a({
tabIndex: this.state.tabActive === index ? 0 : -1, id: id ? id + "-tab" : "tab-" + index,
"aria-controls": "panel-" + index, tabIndex: isTabSelected ? 0 : -1,
"aria-controls": id ? id + "-panel" : "panel-" + index,
"aria-selected": isTabSelected, "aria-selected": isTabSelected,
role: "tab", role: "tab",
onClick: this.onClickTab.bind(this, index), onClick: this.onClickTab.bind(this, index),
@ -297,12 +297,11 @@ define(function (require, exports, module) {
let selectedIndex = this.state.tabActive; let selectedIndex = this.state.tabActive;
let panels = this.props.children let panels = this.props.children
.map(tab => { .map((tab) => typeof tab === "function" ? tab() : tab)
return typeof tab === "function" ? tab() : tab; .filter((tab) => tab)
}).filter(tab => { .map((tab, index) => {
return tab; let selected = selectedIndex === index;
}).map((tab, index) => { let id = tab.props.id;
let selected = selectedIndex == index;
// Use 'visibility:hidden' + 'width/height:0' for hiding // Use 'visibility:hidden' + 'width/height:0' for hiding
// content of non-selected tab. It's faster (not sure why) // content of non-selected tab. It's faster (not sure why)
@ -315,12 +314,12 @@ define(function (require, exports, module) {
return ( return (
DOM.div({ DOM.div({
id: id ? id + "-panel" : "panel-" + index,
key: index, key: index,
id: "panel-" + index,
style: style, style: style,
className: "tab-panel-box", className: "tab-panel-box",
role: "tabpanel", role: "tabpanel",
"aria-labelledby": "tab-" + index, "aria-labelledby": id ? id + "-tab" : "tab-" + index,
}, },
(selected || this.state.created[index]) ? tab : null (selected || this.state.created[index]) ? tab : null
) )
@ -335,12 +334,10 @@ define(function (require, exports, module) {
}, },
render: function () { render: function () {
let classNames = ["tabs", this.props.className].join(" ");
return ( return (
DOM.div({className: classNames}, DOM.div({ className: ["tabs", this.props.className].join(" ") },
this.renderMenuItems(), this.renderMenuItems(),
this.renderPanels() this.renderPanels(),
) )
); );
}, },