Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  App.js   Sprache: JAVA

 
/* 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 {
  Component,
  createFactory,
} = require("resource://devtools/client/shared/vendor/react.js");
loader.lazyRequireGetter(
  this,
  "PropTypes",
  "resource://devtools/client/shared/vendor/react-prop-types.js"
);
const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
const {
  connect,
} = require("resource://devtools/client/shared/redux/visibility-handler-connect.js");

const actions = require("resource://devtools/client/webconsole/actions/index.js");
const {
  FILTERBAR_DISPLAY_MODES,
} = require("resource://devtools/client/webconsole/constants.js");

// We directly require Components that we know are going to be used right away
const ConsoleOutput = createFactory(
  require("resource://devtools/client/webconsole/components/Output/ConsoleOutput.js")
);
const FilterBar = createFactory(
  require("resource://devtools/client/webconsole/components/FilterBar/FilterBar.js")
);
const ReverseSearchInput = createFactory(
  require("resource://devtools/client/webconsole/components/Input/ReverseSearchInput.js")
);
const JSTerm = createFactory(
  require("resource://devtools/client/webconsole/components/Input/JSTerm.js")
);
const ConfirmDialog = createFactory(
  require("resource://devtools/client/webconsole/components/Input/ConfirmDialog.js")
);
const EagerEvaluation = createFactory(
  require("resource://devtools/client/webconsole/components/Input/EagerEvaluation.js")
);
const EvaluationNotification = createFactory(
  require("resource://devtools/client/webconsole/components/Input/EvaluationNotification.js")
);

// And lazy load the ones that may not be used.
loader.lazyGetter(this"SideBar", () =>
  createFactory(
    require("resource://devtools/client/webconsole/components/SideBar.js")
  )
);

loader.lazyGetter(this"EditorToolbar", () =>
  createFactory(
    require("resource://devtools/client/webconsole/components/Input/EditorToolbar.js")
  )
);

loader.lazyGetter(this"NotificationBox", () =>
  createFactory(
    require("resource://devtools/client/shared/components/NotificationBox.js")
      .NotificationBox
  )
);
loader.lazyRequireGetter(
  this,
  ["getNotificationWithValue""PriorityLevels"],
  "resource://devtools/client/shared/components/NotificationBox.js",
  true
);

loader.lazyGetter(this"GridElementWidthResizer", () =>
  createFactory(
    require("resource://devtools/client/shared/components/splitter/GridElementWidthResizer.js")
  )
);

loader.lazyGetter(this"ChromeDebugToolbar", () =>
  createFactory(
    require("resource://devtools/client/framework/components/ChromeDebugToolbar.js")
  )
);

const l10n = require("resource://devtools/client/webconsole/utils/l10n.js");
const {
  Utils: WebConsoleUtils,
} = require("resource://devtools/client/webconsole/utils.js");

const SELF_XSS_OK = l10n.getStr("selfxss.okstring");
const SELF_XSS_MSG = l10n.getFormatStr("selfxss.msg", [SELF_XSS_OK]);

const {
  getAllNotifications,
} = require("resource://devtools/client/webconsole/selectors/notifications.js");
const { div } = dom;
const isMacOS = Services.appinfo.OS === "Darwin";

/**
 * Console root Application component.
 */

class App extends Component {
  static get propTypes() {
    return {
      dispatch: PropTypes.func.isRequired,
      webConsoleUI: PropTypes.object.isRequired,
      notifications: PropTypes.object,
      onFirstMeaningfulPaint: PropTypes.func.isRequired,
      serviceContainer: PropTypes.object.isRequired,
      closeSplitConsole: PropTypes.func.isRequired,
      autocomplete: PropTypes.bool,
      currentReverseSearchEntry: PropTypes.string,
      reverseSearchInputVisible: PropTypes.bool,
      reverseSearchInitialValue: PropTypes.string,
      editorMode: PropTypes.bool,
      editorWidth: PropTypes.number,
      inputEnabled: PropTypes.bool,
      sidebarVisible: PropTypes.bool.isRequired,
      eagerEvaluationEnabled: PropTypes.bool.isRequired,
      filterBarDisplayMode: PropTypes.oneOf([
        ...Object.values(FILTERBAR_DISPLAY_MODES),
      ]).isRequired,
      showEvaluationContextSelector: PropTypes.bool,
    };
  }

  constructor(props) {
    super(props);

    this.onClick = this.onClick.bind(this);
    this.onPaste = this.onPaste.bind(this);
    this.onKeyDown = this.onKeyDown.bind(this);
    this.onBlur = this.onBlur.bind(this);
  }

  componentDidMount() {
    window.addEventListener("blur"this.onBlur);
  }

  onBlur() {
    this.props.dispatch(actions.autocompleteClear());
  }

  onKeyDown(event) {
    const { dispatch, webConsoleUI } = this.props;

    if (
      (!isMacOS && event.key === "F9") ||
      (isMacOS && event.key === "r" && event.ctrlKey === true)
    ) {
      const initialValue =
        webConsoleUI.jsterm && webConsoleUI.jsterm.getSelectedText();

      dispatch(
        actions.reverseSearchInputToggle({ initialValue, access: "keyboard" })
      );
      event.stopPropagation();
      // Prevent Reader Mode to be enabled (See Bug 1682340)
      event.preventDefault();
    }

    if (
      event.key.toLowerCase() === "b" &&
      ((isMacOS && event.metaKey) || (!isMacOS && event.ctrlKey))
    ) {
      event.stopPropagation();
      event.preventDefault();
      dispatch(actions.editorToggle());
    }
  }

  onClick(event) {
    const target = event.originalTarget || event.target;
    const { reverseSearchInputVisible, dispatch, webConsoleUI } = this.props;

    if (
      reverseSearchInputVisible === true &&
      !target.closest(".reverse-search")
    ) {
      event.preventDefault();
      event.stopPropagation();
      dispatch(actions.reverseSearchInputToggle());
      return;
    }

    // Do not focus on middle/right-click or 2+ clicks.
    if (event.detail !== 1 || event.button !== 0) {
      return;
    }

    // Do not focus if a link was clicked
    if (target.closest("a")) {
      return;
    }

    // Do not focus if an input field was clicked
    if (target.closest("input")) {
      return;
    }

    // Do not focus if the click happened in the reverse search toolbar.
    if (target.closest(".reverse-search")) {
      return;
    }

    // Do not focus if something other than the output region was clicked
    // (including e.g. the clear messages button in toolbar)
    if (!target.closest(".webconsole-app")) {
      return;
    }

    // Do not focus if something is selected
    const selection = webConsoleUI.document.defaultView.getSelection();
    if (selection && !selection.isCollapsed) {
      return;
    }

    if (webConsoleUI?.jsterm) {
      webConsoleUI.jsterm.focus();
    }
  }

  onPaste(event) {
    const { dispatch, webConsoleUI, notifications } = this.props;

    const { usageCount, CONSOLE_ENTRY_THRESHOLD } = WebConsoleUtils;

    // Bail out if self-xss notification is suppressed.
    if (
      webConsoleUI.isBrowserConsole ||
      usageCount >= CONSOLE_ENTRY_THRESHOLD
    ) {
      return;
    }

    // Stop event propagation, so the clipboard content is *not* inserted.
    event.preventDefault();
    event.stopPropagation();

    // Bail out if self-xss notification is already there.
    if (getNotificationWithValue(notifications, "selfxss-notification")) {
      return;
    }

    const input = event.target;

    // Cleanup function if notification is closed by the user.
    const removeCallback = eventType => {
      if (eventType == "removed") {
        input.removeEventListener("keyup", pasteKeyUpHandler);
        dispatch(actions.removeNotification("selfxss-notification"));
      }
    };

    // Create self-xss notification
    dispatch(
      actions.appendNotification(
        SELF_XSS_MSG,
        "selfxss-notification",
        null,
        PriorityLevels.PRIORITY_WARNING_HIGH,
        null,
        removeCallback
      )
    );

    // Remove notification automatically when the user types "allow pasting".
    const pasteKeyUpHandler = e => {
      const { value } = e.target;
      if (value.includes(SELF_XSS_OK)) {
        dispatch(actions.removeNotification("selfxss-notification"));
        input.removeEventListener("keyup", pasteKeyUpHandler);
        WebConsoleUtils.usageCount = WebConsoleUtils.CONSOLE_ENTRY_THRESHOLD;
      }
    };

    input.addEventListener("keyup", pasteKeyUpHandler);
  }

  renderChromeDebugToolbar() {
    const { webConsoleUI } = this.props;
    if (!webConsoleUI.isBrowserConsole) {
      return null;
    }
    return ChromeDebugToolbar({
      // This should always be true at this point
      isBrowserConsole: webConsoleUI.isBrowserConsole,
    });
  }

  renderFilterBar() {
    const { closeSplitConsole, filterBarDisplayMode, webConsoleUI } =
      this.props;

    return FilterBar({
      key: "filterbar",
      closeSplitConsole,
      displayMode: filterBarDisplayMode,
      webConsoleUI,
    });
  }

  renderEditorToolbar() {
    const {
      editorMode,
      dispatch,
      reverseSearchInputVisible,
      serviceContainer,
      webConsoleUI,
      showEvaluationContextSelector,
      inputEnabled,
    } = this.props;

    if (!inputEnabled) {
      return null;
    }

    return editorMode
      ? EditorToolbar({
          key: "editor-toolbar",
          editorMode,
          dispatch,
          reverseSearchInputVisible,
          serviceContainer,
          showEvaluationContextSelector,
          webConsoleUI,
        })
      : null;
  }

  renderConsoleOutput() {
    const { onFirstMeaningfulPaint, serviceContainer, editorMode } = this.props;

    return ConsoleOutput({
      key: "console-output",
      serviceContainer,
      onFirstMeaningfulPaint,
      editorMode,
    });
  }

  renderJsTerm() {
    const {
      webConsoleUI,
      serviceContainer,
      autocomplete,
      editorMode,
      editorWidth,
      inputEnabled,
    } = this.props;

    return JSTerm({
      key: "jsterm",
      webConsoleUI,
      serviceContainer,
      onPaste: this.onPaste,
      autocomplete,
      editorMode,
      editorWidth,
      inputEnabled,
    });
  }

  renderEagerEvaluation() {
    const { eagerEvaluationEnabled, serviceContainer, inputEnabled } =
      this.props;

    if (!eagerEvaluationEnabled || !inputEnabled) {
      return null;
    }

    return EagerEvaluation({ serviceContainer });
  }

  renderReverseSearch() {
    const { serviceContainer, reverseSearchInitialValue } = this.props;

    return ReverseSearchInput({
      key: "reverse-search-input",
      setInputValue: serviceContainer.setInputValue,
      focusInput: serviceContainer.focusInput,
      initialValue: reverseSearchInitialValue,
    });
  }

  renderSideBar() {
    const { serviceContainer, sidebarVisible } = this.props;
    return sidebarVisible
      ? SideBar({
          key: "sidebar",
          serviceContainer,
          visible: sidebarVisible,
        })
      : null;
  }

  renderNotificationBox() {
    const { notifications, editorMode } = this.props;

    return notifications && notifications.size > 0
      ? NotificationBox({
          id: "webconsole-notificationbox",
          key: "notification-box",
          displayBorderTop: !editorMode,
          displayBorderBottom: editorMode,
          wrapping: true,
          notifications,
        })
      : null;
  }

  renderConfirmDialog() {
    const { webConsoleUI, serviceContainer } = this.props;

    return ConfirmDialog({
      webConsoleUI,
      serviceContainer,
      key: "confirm-dialog",
    });
  }

  renderRootElement(children) {
    const { editorMode, sidebarVisible, inputEnabled, eagerEvaluationEnabled } =
      this.props;

    const classNames = ["webconsole-app"];
    if (sidebarVisible) {
      classNames.push("sidebar-visible");
    }
    if (editorMode && inputEnabled) {
      classNames.push("jsterm-editor");
    }

    if (eagerEvaluationEnabled && inputEnabled) {
      classNames.push("eager-evaluation");
    }

    return div(
      {
        className: classNames.join(" "),
        onKeyDown: this.onKeyDown,
        onClick: this.onClick,
        ref: node => {
          this.node = node;
        },
      },
      children
    );
  }

  render() {
    const { webConsoleUI, editorMode, dispatch, inputEnabled } = this.props;

    const chromeDebugToolbar = this.renderChromeDebugToolbar();
    const filterBar = this.renderFilterBar();
    const editorToolbar = this.renderEditorToolbar();
    const consoleOutput = this.renderConsoleOutput();
    const notificationBox = this.renderNotificationBox();
    const jsterm = this.renderJsTerm();
    const eager = this.renderEagerEvaluation();
    const evaluationNotification = EvaluationNotification();
    const reverseSearch = this.renderReverseSearch();
    const sidebar = this.renderSideBar();
    const confirmDialog = this.renderConfirmDialog();

    return this.renderRootElement([
      chromeDebugToolbar,
      filterBar,
      editorToolbar,
      dom.div(
        { className: "flexible-output-input", key: "in-out-container" },
        consoleOutput,
        notificationBox,
        jsterm,
        eager,
        evaluationNotification
      ),
      editorMode && inputEnabled
        ? GridElementWidthResizer({
            key: "editor-resizer",
            enabled: editorMode,
            position: "end",
            className: "editor-resizer",
            getControlledElementNode: () => webConsoleUI.jsterm.node,
            onResizeEnd: width => dispatch(actions.setEditorWidth(width)),
          })
        : null,
      reverseSearch,
      sidebar,
      confirmDialog,
    ]);
  }
}

const mapStateToProps = state => ({
  notifications: getAllNotifications(state),
  reverseSearchInputVisible: state.ui.reverseSearchInputVisible,
  reverseSearchInitialValue: state.ui.reverseSearchInitialValue,
  editorMode: state.ui.editor,
  editorWidth: state.ui.editorWidth,
  sidebarVisible: state.ui.sidebarVisible,
  filterBarDisplayMode: state.ui.filterBarDisplayMode,
  eagerEvaluationEnabled: state.prefs.eagerEvaluation,
  autocomplete: state.prefs.autocomplete,
  showEvaluationContextSelector: state.ui.showEvaluationContextSelector,
});

const mapDispatchToProps = dispatch => ({
  dispatch,
});

module.exports = connect(mapStateToProps, mapDispatchToProps)(App);

100%


¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge