From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/client/shared/components/.eslintrc.js | 7 + devtools/client/shared/components/frame.js | 239 ++++++ devtools/client/shared/components/h-split-box.js | 154 ++++ devtools/client/shared/components/moz.build | 27 + .../client/shared/components/notification-box.css | 95 +++ .../client/shared/components/notification-box.js | 263 ++++++ devtools/client/shared/components/reps/array.js | 186 +++++ .../client/shared/components/reps/attribute.js | 70 ++ devtools/client/shared/components/reps/caption.js | 31 + .../client/shared/components/reps/comment-node.js | 60 ++ .../client/shared/components/reps/date-time.js | 70 ++ devtools/client/shared/components/reps/document.js | 78 ++ .../client/shared/components/reps/element-node.js | 114 +++ devtools/client/shared/components/reps/event.js | 81 ++ devtools/client/shared/components/reps/function.js | 73 ++ .../client/shared/components/reps/grip-array.js | 198 +++++ devtools/client/shared/components/reps/grip-map.js | 193 +++++ devtools/client/shared/components/reps/grip.js | 247 ++++++ devtools/client/shared/components/reps/infinity.js | 41 + .../client/shared/components/reps/long-string.js | 71 ++ devtools/client/shared/components/reps/moz.build | 40 + devtools/client/shared/components/reps/nan.js | 41 + devtools/client/shared/components/reps/null.js | 46 ++ devtools/client/shared/components/reps/number.js | 51 ++ .../shared/components/reps/object-with-text.js | 76 ++ .../shared/components/reps/object-with-url.js | 76 ++ devtools/client/shared/components/reps/object.js | 171 ++++ devtools/client/shared/components/reps/promise.js | 111 +++ devtools/client/shared/components/reps/prop-rep.js | 70 ++ devtools/client/shared/components/reps/regexp.js | 63 ++ .../client/shared/components/reps/rep-utils.js | 160 ++++ devtools/client/shared/components/reps/rep.js | 144 ++++ devtools/client/shared/components/reps/reps.css | 174 ++++ devtools/client/shared/components/reps/string.js | 69 ++ .../client/shared/components/reps/stylesheet.js | 77 ++ devtools/client/shared/components/reps/symbol.js | 48 ++ .../client/shared/components/reps/text-node.js | 94 +++ .../client/shared/components/reps/undefined.js | 46 ++ devtools/client/shared/components/reps/window.js | 73 ++ devtools/client/shared/components/search-box.js | 110 +++ .../client/shared/components/sidebar-toggle.css | 32 + .../client/shared/components/sidebar-toggle.js | 66 ++ .../client/shared/components/splitter/draggable.js | 54 ++ .../client/shared/components/splitter/moz.build | 11 + .../shared/components/splitter/split-box.css | 88 ++ .../client/shared/components/splitter/split-box.js | 205 +++++ devtools/client/shared/components/stack-trace.js | 68 ++ devtools/client/shared/components/tabs/moz.build | 12 + devtools/client/shared/components/tabs/tabbar.css | 53 ++ devtools/client/shared/components/tabs/tabbar.js | 204 +++++ devtools/client/shared/components/tabs/tabs.css | 183 +++++ devtools/client/shared/components/tabs/tabs.js | 369 +++++++++ .../shared/components/test/browser/.eslintrc.js | 6 + .../shared/components/test/browser/browser.ini | 7 + .../test/browser/browser_notification_box_basic.js | 36 + .../shared/components/test/mochitest/.eslintrc.js | 6 + .../shared/components/test/mochitest/chrome.ini | 51 ++ .../shared/components/test/mochitest/head.js | 217 +++++ .../test/mochitest/test_HSplitBox_01.html | 126 +++ .../components/test/mochitest/test_frame_01.html | 309 +++++++ .../test/mochitest/test_notification_box_01.html | 108 +++ .../test/mochitest/test_notification_box_02.html | 70 ++ .../test/mochitest/test_notification_box_03.html | 84 ++ .../components/test/mochitest/test_reps_array.html | 259 ++++++ .../test/mochitest/test_reps_attribute.html | 56 ++ .../test/mochitest/test_reps_comment-node.html | 80 ++ .../test/mochitest/test_reps_date-time.html | 79 ++ .../test/mochitest/test_reps_document.html | 56 ++ .../test/mochitest/test_reps_element-node.html | 341 ++++++++ .../components/test/mochitest/test_reps_event.html | 300 +++++++ .../test/mochitest/test_reps_function.html | 206 +++++ .../test/mochitest/test_reps_grip-array.html | 707 ++++++++++++++++ .../test/mochitest/test_reps_grip-map.html | 405 ++++++++++ .../components/test/mochitest/test_reps_grip.html | 887 +++++++++++++++++++++ .../test/mochitest/test_reps_infinity.html | 73 ++ .../test/mochitest/test_reps_long-string.html | 125 +++ .../components/test/mochitest/test_reps_nan.html | 48 ++ .../components/test/mochitest/test_reps_null.html | 44 + .../test/mochitest/test_reps_number.html | 97 +++ .../test/mochitest/test_reps_object-with-text.html | 54 ++ .../test/mochitest/test_reps_object-with-url.html | 60 ++ .../test/mochitest/test_reps_object.html | 225 ++++++ .../test/mochitest/test_reps_promise.html | 333 ++++++++ .../test/mochitest/test_reps_regexp.html | 51 ++ .../test/mochitest/test_reps_string.html | 79 ++ .../test/mochitest/test_reps_stylesheet.html | 54 ++ .../test/mochitest/test_reps_symbol.html | 77 ++ .../test/mochitest/test_reps_text-node.html | 115 +++ .../test/mochitest/test_reps_undefined.html | 47 ++ .../test/mochitest/test_reps_window.html | 58 ++ .../test/mochitest/test_sidebar_toggle.html | 56 ++ .../test/mochitest/test_stack-trace.html | 102 +++ .../test/mochitest/test_tabs_accessibility.html | 79 ++ .../components/test/mochitest/test_tabs_menu.html | 81 ++ .../components/test/mochitest/test_tree_01.html | 64 ++ .../components/test/mochitest/test_tree_02.html | 45 ++ .../components/test/mochitest/test_tree_03.html | 46 ++ .../components/test/mochitest/test_tree_04.html | 128 +++ .../components/test/mochitest/test_tree_05.html | 83 ++ .../components/test/mochitest/test_tree_06.html | 320 ++++++++ .../components/test/mochitest/test_tree_07.html | 64 ++ .../components/test/mochitest/test_tree_08.html | 51 ++ .../components/test/mochitest/test_tree_09.html | 77 ++ .../components/test/mochitest/test_tree_10.html | 52 ++ .../components/test/mochitest/test_tree_11.html | 92 +++ devtools/client/shared/components/tree.js | 773 ++++++++++++++++++ .../client/shared/components/tree/label-cell.js | 66 ++ devtools/client/shared/components/tree/moz.build | 14 + .../shared/components/tree/object-provider.js | 90 +++ .../client/shared/components/tree/tree-cell.js | 101 +++ .../client/shared/components/tree/tree-header.js | 100 +++ devtools/client/shared/components/tree/tree-row.js | 184 +++++ .../client/shared/components/tree/tree-view.css | 157 ++++ .../client/shared/components/tree/tree-view.js | 352 ++++++++ 114 files changed, 14496 insertions(+) create mode 100644 devtools/client/shared/components/.eslintrc.js create mode 100644 devtools/client/shared/components/frame.js create mode 100644 devtools/client/shared/components/h-split-box.js create mode 100644 devtools/client/shared/components/moz.build create mode 100644 devtools/client/shared/components/notification-box.css create mode 100644 devtools/client/shared/components/notification-box.js create mode 100644 devtools/client/shared/components/reps/array.js create mode 100644 devtools/client/shared/components/reps/attribute.js create mode 100644 devtools/client/shared/components/reps/caption.js create mode 100644 devtools/client/shared/components/reps/comment-node.js create mode 100644 devtools/client/shared/components/reps/date-time.js create mode 100644 devtools/client/shared/components/reps/document.js create mode 100644 devtools/client/shared/components/reps/element-node.js create mode 100644 devtools/client/shared/components/reps/event.js create mode 100644 devtools/client/shared/components/reps/function.js create mode 100644 devtools/client/shared/components/reps/grip-array.js create mode 100644 devtools/client/shared/components/reps/grip-map.js create mode 100644 devtools/client/shared/components/reps/grip.js create mode 100644 devtools/client/shared/components/reps/infinity.js create mode 100644 devtools/client/shared/components/reps/long-string.js create mode 100644 devtools/client/shared/components/reps/moz.build create mode 100644 devtools/client/shared/components/reps/nan.js create mode 100644 devtools/client/shared/components/reps/null.js create mode 100644 devtools/client/shared/components/reps/number.js create mode 100644 devtools/client/shared/components/reps/object-with-text.js create mode 100644 devtools/client/shared/components/reps/object-with-url.js create mode 100644 devtools/client/shared/components/reps/object.js create mode 100644 devtools/client/shared/components/reps/promise.js create mode 100644 devtools/client/shared/components/reps/prop-rep.js create mode 100644 devtools/client/shared/components/reps/regexp.js create mode 100644 devtools/client/shared/components/reps/rep-utils.js create mode 100644 devtools/client/shared/components/reps/rep.js create mode 100644 devtools/client/shared/components/reps/reps.css create mode 100644 devtools/client/shared/components/reps/string.js create mode 100644 devtools/client/shared/components/reps/stylesheet.js create mode 100644 devtools/client/shared/components/reps/symbol.js create mode 100644 devtools/client/shared/components/reps/text-node.js create mode 100644 devtools/client/shared/components/reps/undefined.js create mode 100644 devtools/client/shared/components/reps/window.js create mode 100644 devtools/client/shared/components/search-box.js create mode 100644 devtools/client/shared/components/sidebar-toggle.css create mode 100644 devtools/client/shared/components/sidebar-toggle.js create mode 100644 devtools/client/shared/components/splitter/draggable.js create mode 100644 devtools/client/shared/components/splitter/moz.build create mode 100644 devtools/client/shared/components/splitter/split-box.css create mode 100644 devtools/client/shared/components/splitter/split-box.js create mode 100644 devtools/client/shared/components/stack-trace.js create mode 100644 devtools/client/shared/components/tabs/moz.build create mode 100644 devtools/client/shared/components/tabs/tabbar.css create mode 100644 devtools/client/shared/components/tabs/tabbar.js create mode 100644 devtools/client/shared/components/tabs/tabs.css create mode 100644 devtools/client/shared/components/tabs/tabs.js create mode 100644 devtools/client/shared/components/test/browser/.eslintrc.js create mode 100644 devtools/client/shared/components/test/browser/browser.ini create mode 100644 devtools/client/shared/components/test/browser/browser_notification_box_basic.js create mode 100644 devtools/client/shared/components/test/mochitest/.eslintrc.js create mode 100644 devtools/client/shared/components/test/mochitest/chrome.ini create mode 100644 devtools/client/shared/components/test/mochitest/head.js create mode 100644 devtools/client/shared/components/test/mochitest/test_HSplitBox_01.html create mode 100644 devtools/client/shared/components/test/mochitest/test_frame_01.html create mode 100644 devtools/client/shared/components/test/mochitest/test_notification_box_01.html create mode 100644 devtools/client/shared/components/test/mochitest/test_notification_box_02.html create mode 100644 devtools/client/shared/components/test/mochitest/test_notification_box_03.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_array.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_attribute.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_comment-node.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_date-time.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_document.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_element-node.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_event.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_function.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_grip-array.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_grip-map.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_grip.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_infinity.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_long-string.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_nan.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_null.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_number.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_object-with-text.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_object-with-url.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_object.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_promise.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_regexp.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_string.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_stylesheet.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_symbol.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_text-node.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_undefined.html create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_window.html create mode 100644 devtools/client/shared/components/test/mochitest/test_sidebar_toggle.html create mode 100644 devtools/client/shared/components/test/mochitest/test_stack-trace.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tabs_accessibility.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tabs_menu.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_01.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_02.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_03.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_04.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_05.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_06.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_07.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_08.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_09.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_10.html create mode 100644 devtools/client/shared/components/test/mochitest/test_tree_11.html create mode 100644 devtools/client/shared/components/tree.js create mode 100644 devtools/client/shared/components/tree/label-cell.js create mode 100644 devtools/client/shared/components/tree/moz.build create mode 100644 devtools/client/shared/components/tree/object-provider.js create mode 100644 devtools/client/shared/components/tree/tree-cell.js create mode 100644 devtools/client/shared/components/tree/tree-header.js create mode 100644 devtools/client/shared/components/tree/tree-row.js create mode 100644 devtools/client/shared/components/tree/tree-view.css create mode 100644 devtools/client/shared/components/tree/tree-view.js (limited to 'devtools/client/shared/components') diff --git a/devtools/client/shared/components/.eslintrc.js b/devtools/client/shared/components/.eslintrc.js new file mode 100644 index 000000000..3112895e9 --- /dev/null +++ b/devtools/client/shared/components/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "globals": { + "define": true, + } +}; diff --git a/devtools/client/shared/components/frame.js b/devtools/client/shared/components/frame.js new file mode 100644 index 000000000..5abe5f057 --- /dev/null +++ b/devtools/client/shared/components/frame.js @@ -0,0 +1,239 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react"); +const { getSourceNames, parseURL, + isScratchpadScheme, getSourceMappedFile } = require("devtools/client/shared/source-utils"); +const { LocalizationHelper } = require("devtools/shared/l10n"); + +const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); +const webl10n = new LocalizationHelper("devtools/client/locales/webconsole.properties"); + +module.exports = createClass({ + displayName: "Frame", + + propTypes: { + // SavedFrame, or an object containing all the required properties. + frame: PropTypes.shape({ + functionDisplayName: PropTypes.string, + source: PropTypes.string.isRequired, + line: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), + column: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), + }).isRequired, + // Clicking on the frame link -- probably should link to the debugger. + onClick: PropTypes.func.isRequired, + // Option to display a function name before the source link. + showFunctionName: PropTypes.bool, + // Option to display a function name even if it's anonymous. + showAnonymousFunctionName: PropTypes.bool, + // Option to display a host name after the source link. + showHost: PropTypes.bool, + // Option to display a host name if the filename is empty or just '/' + showEmptyPathAsHost: PropTypes.bool, + // Option to display a full source instead of just the filename. + showFullSourceUrl: PropTypes.bool, + // Service to enable the source map feature for console. + sourceMapService: PropTypes.object, + }, + + getDefaultProps() { + return { + showFunctionName: false, + showAnonymousFunctionName: false, + showHost: false, + showEmptyPathAsHost: false, + showFullSourceUrl: false, + }; + }, + + componentWillMount() { + const sourceMapService = this.props.sourceMapService; + if (sourceMapService) { + const source = this.getSource(); + sourceMapService.subscribe(source, this.onSourceUpdated); + } + }, + + componentWillUnmount() { + const sourceMapService = this.props.sourceMapService; + if (sourceMapService) { + const source = this.getSource(); + sourceMapService.unsubscribe(source, this.onSourceUpdated); + } + }, + + /** + * Component method to update the FrameView when a resolved location is available + * @param event + * @param location + */ + onSourceUpdated(event, location, resolvedLocation) { + const frame = this.getFrame(resolvedLocation); + this.setState({ + frame, + isSourceMapped: true, + }); + }, + + /** + * Utility method to convert the Frame object to the + * Source Object model required by SourceMapService + * @param frame + * @returns {{url: *, line: *, column: *}} + */ + getSource(frame) { + frame = frame || this.props.frame; + const { source, line, column } = frame; + return { + url: source, + line, + column, + }; + }, + + /** + * Utility method to convert the Source object model to the + * Frame object model required by FrameView class. + * @param source + * @returns {{source: *, line: *, column: *, functionDisplayName: *}} + */ + getFrame(source) { + const { url, line, column } = source; + return { + source: url, + line, + column, + functionDisplayName: this.props.frame.functionDisplayName, + }; + }, + + render() { + let frame, isSourceMapped; + let { + onClick, + showFunctionName, + showAnonymousFunctionName, + showHost, + showEmptyPathAsHost, + showFullSourceUrl + } = this.props; + + if (this.state && this.state.isSourceMapped) { + frame = this.state.frame; + isSourceMapped = this.state.isSourceMapped; + } else { + frame = this.props.frame; + } + + let source = frame.source ? String(frame.source) : ""; + let line = frame.line != void 0 ? Number(frame.line) : null; + let column = frame.column != void 0 ? Number(frame.column) : null; + + const { short, long, host } = getSourceNames(source); + // Reparse the URL to determine if we should link this; `getSourceNames` + // has already cached this indirectly. We don't want to attempt to + // link to "self-hosted" and "(unknown)". However, we do want to link + // to Scratchpad URIs. + // Source mapped sources might not necessary linkable, but they + // are still valid in the debugger. + const isLinkable = !!(isScratchpadScheme(source) || parseURL(source)) + || isSourceMapped; + const elements = []; + const sourceElements = []; + let sourceEl; + + let tooltip = long; + + // Exclude all falsy values, including `0`, as line numbers start with 1. + if (line) { + tooltip += `:${line}`; + // Intentionally exclude 0 + if (column) { + tooltip += `:${column}`; + } + } + + let attributes = { + "data-url": long, + className: "frame-link", + }; + + if (showFunctionName) { + let functionDisplayName = frame.functionDisplayName; + if (!functionDisplayName && showAnonymousFunctionName) { + functionDisplayName = webl10n.getStr("stacktrace.anonymousFunction"); + } + + if (functionDisplayName) { + elements.push( + dom.span({ className: "frame-link-function-display-name" }, + functionDisplayName), + " " + ); + } + } + + let displaySource = showFullSourceUrl ? long : short; + if (isSourceMapped) { + displaySource = getSourceMappedFile(displaySource); + } else if (showEmptyPathAsHost && (displaySource === "" || displaySource === "/")) { + displaySource = host; + } + + sourceElements.push(dom.span({ + className: "frame-link-filename", + }, displaySource)); + + // If we have a line number > 0. + if (line) { + let lineInfo = `:${line}`; + // Add `data-line` attribute for testing + attributes["data-line"] = line; + + // Intentionally exclude 0 + if (column) { + lineInfo += `:${column}`; + // Add `data-column` attribute for testing + attributes["data-column"] = column; + } + + sourceElements.push(dom.span({ className: "frame-link-line" }, lineInfo)); + } + + // Inner el is useful for achieving ellipsis on the left and correct LTR/RTL + // ordering. See CSS styles for frame-link-source-[inner] and bug 1290056. + let sourceInnerEl = dom.span({ + className: "frame-link-source-inner", + title: isLinkable ? + l10n.getFormatStr("frame.viewsourceindebugger", tooltip) : tooltip, + }, sourceElements); + + // If source is not a URL (self-hosted, eval, etc.), don't make + // it an anchor link, as we can't link to it. + if (isLinkable) { + sourceEl = dom.a({ + onClick: e => { + e.preventDefault(); + onClick(this.getSource(frame)); + }, + href: source, + className: "frame-link-source", + draggable: false, + }, sourceInnerEl); + } else { + sourceEl = dom.span({ + className: "frame-link-source", + }, sourceInnerEl); + } + elements.push(sourceEl); + + if (showHost && host) { + elements.push(" ", dom.span({ className: "frame-link-host" }, host)); + } + + return dom.span(attributes, ...elements); + } +}); diff --git a/devtools/client/shared/components/h-split-box.js b/devtools/client/shared/components/h-split-box.js new file mode 100644 index 000000000..d804a6ba1 --- /dev/null +++ b/devtools/client/shared/components/h-split-box.js @@ -0,0 +1,154 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* eslint-env browser */ +"use strict"; + +// A box with a start and a end pane, separated by a dragable splitter that +// allows the user to resize the relative widths of the panes. +// +// +-----------------------+---------------------+ +// | | | +// | | | +// | S | +// | Start Pane p End Pane | +// | l | +// | i | +// | t | +// | t | +// | e | +// | r | +// | | | +// | | | +// +-----------------------+---------------------+ + +const { + DOM: dom, + createClass, + PropTypes, +} = require("devtools/client/shared/vendor/react"); +const { assert } = require("devtools/shared/DevToolsUtils"); + +module.exports = createClass({ + displayName: "HSplitBox", + + propTypes: { + // The contents of the start pane. + start: PropTypes.any.isRequired, + + // The contents of the end pane. + end: PropTypes.any.isRequired, + + // The relative width of the start pane, expressed as a number between 0 and + // 1. The relative width of the end pane is 1 - startWidth. For example, + // with startWidth = .5, both panes are of equal width; with startWidth = + // .25, the start panel will take up 1/4 width and the end panel will take + // up 3/4 width. + startWidth: PropTypes.number, + + // A minimum css width value for the start and end panes. + minStartWidth: PropTypes.any, + minEndWidth: PropTypes.any, + + // A callback fired when the user drags the splitter to resize the relative + // pane widths. The function is passed the startWidth value that would put + // the splitter underneath the users mouse. + onResize: PropTypes.func.isRequired, + }, + + getDefaultProps() { + return { + startWidth: 0.5, + minStartWidth: "20px", + minEndWidth: "20px", + }; + }, + + getInitialState() { + return { + mouseDown: false + }; + }, + + componentDidMount() { + document.defaultView.top.addEventListener("mouseup", this._onMouseUp, + false); + document.defaultView.top.addEventListener("mousemove", this._onMouseMove, + false); + }, + + componentWillUnmount() { + document.defaultView.top.removeEventListener("mouseup", this._onMouseUp, + false); + document.defaultView.top.removeEventListener("mousemove", this._onMouseMove, + false); + }, + + _onMouseDown(event) { + if (event.button !== 0) { + return; + } + + this.setState({ mouseDown: true }); + event.preventDefault(); + }, + + _onMouseUp(event) { + if (event.button !== 0 || !this.state.mouseDown) { + return; + } + + this.setState({ mouseDown: false }); + event.preventDefault(); + }, + + _onMouseMove(event) { + if (!this.state.mouseDown) { + return; + } + + const rect = this.refs.box.getBoundingClientRect(); + const { left, right } = rect; + const width = right - left; + const relative = event.clientX - left; + this.props.onResize(relative / width); + + event.preventDefault(); + }, + + render() { + /* eslint-disable no-shadow */ + const { start, end, startWidth, minStartWidth, minEndWidth } = this.props; + assert(startWidth => 0 && startWidth <= 1, + "0 <= this.props.startWidth <= 1"); + /* eslint-enable */ + return dom.div( + { + className: "h-split-box", + ref: "box", + }, + + dom.div( + { + className: "h-split-box-pane", + style: { flex: startWidth, minWidth: minStartWidth }, + }, + start + ), + + dom.div({ + className: "devtools-side-splitter", + onMouseDown: this._onMouseDown, + }), + + dom.div( + { + className: "h-split-box-pane", + style: { flex: 1 - startWidth, minWidth: minEndWidth }, + }, + end + ) + ); + } +}); diff --git a/devtools/client/shared/components/moz.build b/devtools/client/shared/components/moz.build new file mode 100644 index 000000000..0d67e90b5 --- /dev/null +++ b/devtools/client/shared/components/moz.build @@ -0,0 +1,27 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + 'reps', + 'splitter', + 'tabs', + 'tree' +] + +DevToolsModules( + 'frame.js', + 'h-split-box.js', + 'notification-box.css', + 'notification-box.js', + 'search-box.js', + 'sidebar-toggle.css', + 'sidebar-toggle.js', + 'stack-trace.js', + 'tree.js', +) + +MOCHITEST_CHROME_MANIFESTS += ['test/mochitest/chrome.ini'] +BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini'] diff --git a/devtools/client/shared/components/notification-box.css b/devtools/client/shared/components/notification-box.css new file mode 100644 index 000000000..83c29b616 --- /dev/null +++ b/devtools/client/shared/components/notification-box.css @@ -0,0 +1,95 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Layout */ + +.notificationbox .notificationInner { + display: flex; + flex-direction: row; +} + +.notificationbox .details { + flex-grow: 1; + display: flex; + flex-direction: row; + align-items: center; +} + +.notificationbox .notification-button { + text-align: right; +} + +.notificationbox .messageText { + flex-grow: 1; +} + +.notificationbox .details:-moz-dir(rtl) +.notificationbox .notificationInner:-moz-dir(rtl) { + flex-direction: row-reverse; +} + +/* Style */ + +.notificationbox .notification { + background-color: InfoBackground; + text-shadow: none; + border-top: 1px solid ThreeDShadow; + border-bottom: 1px solid ThreeDShadow; +} + +.notificationbox .notification[data-type="info"] { + color: -moz-DialogText; + background-color: -moz-Dialog; +} + +.notificationbox .notification[data-type="critical"] { + color: white; + background-image: linear-gradient(rgb(212,0,0), rgb(152,0,0)); +} + +.notificationbox .messageImage { + display: inline-block; + width: 16px; + height: 16px; + margin: 6px; +} + +/* Default icons for notifications */ + +.notificationbox .messageImage[data-type="info"] { + background-image: url("chrome://global/skin/icons/information-16.png"); +} + +.notificationbox .messageImage[data-type="warning"] { + background-image: url("chrome://global/skin/icons/warning-16.png"); +} + +.notificationbox .messageImage[data-type="critical"] { + background-image: url("chrome://global/skin/icons/error-16.png"); +} + +/* Close button */ + +.notificationbox .messageCloseButton { + width: 20px; + height: 20px; + margin: 4px; + margin-inline-end: 8px; + background-image: url("chrome://devtools/skin/images/close.svg"); + background-position: center; + background-color: transparent; + background-repeat: no-repeat; + border-radius: 11px; + filter: invert(0); +} + +.notificationbox .messageCloseButton:hover { + background-color: gray; + filter: invert(1); +} + +.notificationbox .messageCloseButton:active { + background-color: rgba(170, 170, 170, .4); /* --toolbar-tab-hover-active */ +} diff --git a/devtools/client/shared/components/notification-box.js b/devtools/client/shared/components/notification-box.js new file mode 100644 index 000000000..87fc76cd6 --- /dev/null +++ b/devtools/client/shared/components/notification-box.js @@ -0,0 +1,263 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const React = require("devtools/client/shared/vendor/react"); +const Immutable = require("devtools/client/shared/vendor/immutable"); +const { LocalizationHelper } = require("devtools/shared/l10n"); +const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); + +// Shortcuts +const { PropTypes, createClass, DOM } = React; +const { div, span, button } = DOM; + +// Priority Levels +const PriorityLevels = { + PRIORITY_INFO_LOW: 1, + PRIORITY_INFO_MEDIUM: 2, + PRIORITY_INFO_HIGH: 3, + PRIORITY_WARNING_LOW: 4, + PRIORITY_WARNING_MEDIUM: 5, + PRIORITY_WARNING_HIGH: 6, + PRIORITY_CRITICAL_LOW: 7, + PRIORITY_CRITICAL_MEDIUM: 8, + PRIORITY_CRITICAL_HIGH: 9, + PRIORITY_CRITICAL_BLOCK: 10, +}; + +/** + * This component represents Notification Box - HTML alternative for + * binding. + * + * See also MDN for more info about : + * https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/notificationbox + */ +var NotificationBox = createClass({ + displayName: "NotificationBox", + + propTypes: { + // List of notifications appended into the box. + notifications: PropTypes.arrayOf(PropTypes.shape({ + // label to appear on the notification. + label: PropTypes.string.isRequired, + + // Value used to identify the notification + value: PropTypes.string.isRequired, + + // URL of image to appear on the notification. If "" then an icon + // appropriate for the priority level is used. + image: PropTypes.string.isRequired, + + // Notification priority; see Priority Levels. + priority: PropTypes.number.isRequired, + + // Array of button descriptions to appear on the notification. + buttons: PropTypes.arrayOf(PropTypes.shape({ + // Function to be called when the button is activated. + // This function is passed three arguments: + // 1) the NotificationBox component the button is associated with + // 2) the button description as passed to appendNotification. + // 3) the element which was the target of the button press event. + // If the return value from this function is not True, then the + // notification is closed. The notification is also not closed + // if an error is thrown. + callback: PropTypes.func.isRequired, + + // The label to appear on the button. + label: PropTypes.string.isRequired, + + // The accesskey attribute set on the