_connectionTimeout: function () {
    let error = {
      error: "timeout",
      message: l10n.getStr("connectionTimeout"),
    };

    this._connectDefer.reject(error);
  },
Beispiel #2
0
  /**
   * The JavaScript evaluation response handler.
   *
   * @private
   * @param function [callback]
   *        Optional function to invoke when the evaluation result is added to
   *        the output.
   * @param object response
   *        The message received from the server.
   */
  _executeResultCallback(callback, response) {
    if (!this.hud) {
      return;
    }
    if (response.error) {
      console.error("Evaluation error " + response.error + ": " + response.message);
      return;
    }
    let errorMessage = response.exceptionMessage;

    // Wrap thrown strings in Error objects, so `throw "foo"` outputs "Error: foo"
    if (typeof response.exception === "string") {
      errorMessage = new Error(errorMessage).toString();
    }
    let result = response.result;
    let helperResult = response.helperResult;
    let helperHasRawOutput = !!(helperResult || {}).rawOutput;

    if (helperResult && helperResult.type) {
      switch (helperResult.type) {
        case "clearOutput":
          this.clearOutput();
          break;
        case "clearHistory":
          this.clearHistory();
          break;
        case "inspectObject":
          this.inspectObjectActor(helperResult.object);
          break;
        case "error":
          try {
            errorMessage = l10n.getStr(helperResult.message);
          } catch (ex) {
            errorMessage = helperResult.message;
          }
          break;
        case "help":
          this.hud.owner.openLink(HELP_URL);
          break;
        case "copyValueToClipboard":
          clipboardHelper.copyString(helperResult.value);
          break;
      }
    }

    // Hide undefined results coming from JSTerm helper functions.
    if (!errorMessage && result && typeof result == "object" &&
      result.type == "undefined" &&
      helperResult && !helperHasRawOutput) {
      callback && callback();
      return;
    }

    if (this.hud.consoleOutput) {
      this.hud.consoleOutput.dispatchMessageAdd(response, true).then(callback);
    }
  }
Beispiel #3
0
function transformEvaluationResultPacket(packet) {
  let {
    exceptionMessage,
    errorMessageName,
    exceptionDocURL,
    exception,
    exceptionStack,
    frame,
    result,
    helperResult,
    timestamp: timeStamp,
    notes,
  } = packet;

  const parameter = helperResult && helperResult.object
    ? helperResult.object
    : result;

  if (helperResult && helperResult.type === "error") {
    try {
      exceptionMessage = l10n.getStr(helperResult.message);
    } catch (ex) {
      exceptionMessage = helperResult.message;
    }
  } else if (typeof exception === "string") {
    // Wrap thrown strings in Error objects, so `throw "foo"` outputs "Error: foo"
    exceptionMessage = new Error(exceptionMessage).toString();
  }

  const level = typeof exceptionMessage !== "undefined" && exceptionMessage !== null
    ? MESSAGE_LEVEL.ERROR
    : MESSAGE_LEVEL.LOG;

  return new ConsoleMessage({
    source: MESSAGE_SOURCE.JAVASCRIPT,
    type: MESSAGE_TYPE.RESULT,
    helperType: helperResult ? helperResult.type : null,
    level,
    messageText: exceptionMessage,
    parameters: [parameter],
    errorMessageName,
    exceptionDocURL,
    stacktrace: exceptionStack,
    frame,
    timeStamp,
    notes,
    private: packet.private,
  });
}
Beispiel #4
0
function createWarningGroupMessage(id, type, firstMessage) {
  let messageText;
  if (type === MESSAGE_TYPE.CONTENT_BLOCKING_GROUP) {
    messageText = l10n.getStr("webconsole.group.contentBlocked");
  }
  return new ConsoleMessage({
    id,
    level: MESSAGE_LEVEL.WARN,
    source: MESSAGE_SOURCE.CONSOLE_FRONTEND,
    type,
    messageText,
    timeStamp: firstMessage.timeStamp,
    innerWindowID: firstMessage.innerWindowID,
  });
}
Beispiel #5
0
function transformEvaluationResultPacket(packet) {
  let {
    exceptionMessage: messageText,
    exceptionDocURL,
    frame,
    result,
    helperResult,
    timestamp: timeStamp,
    notes,
  } = packet;

  const parameter = helperResult && helperResult.object
    ? helperResult.object
    : result;

  if (helperResult && helperResult.type === "error") {
    try {
      messageText = l10n.getStr(helperResult.message);
    } catch (ex) {
      messageText = helperResult.message;
    }
  }

  const level = messageText ? MESSAGE_LEVEL.ERROR : MESSAGE_LEVEL.LOG;
  return new ConsoleMessage({
    source: MESSAGE_SOURCE.JAVASCRIPT,
    type: MESSAGE_TYPE.RESULT,
    helperType: helperResult ? helperResult.type : null,
    level,
    messageText,
    parameters: [parameter],
    exceptionDocURL,
    frame,
    timeStamp,
    notes,
  });
}
Beispiel #6
0
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const { connect } = require("devtools/client/shared/redux/visibility-handler-connect");

const actions = require("devtools/client/webconsole/actions/index");
const ConsoleOutput = createFactory(require("devtools/client/webconsole/components/ConsoleOutput"));
const FilterBar = createFactory(require("devtools/client/webconsole/components/FilterBar"));
const SideBar = createFactory(require("devtools/client/webconsole/components/SideBar"));
const ReverseSearchInput = createFactory(require("devtools/client/webconsole/components/ReverseSearchInput"));
const JSTerm = createFactory(require("devtools/client/webconsole/components/JSTerm"));
const ConfirmDialog = createFactory(require("devtools/client/webconsole/components/ConfirmDialog"));
const NotificationBox = createFactory(require("devtools/client/shared/components/NotificationBox").NotificationBox);

const l10n = require("devtools/client/webconsole/webconsole-l10n");
const { Utils: WebConsoleUtils } = require("devtools/client/webconsole/utils");

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

const {
  getNotificationWithValue,
  PriorityLevels,
} = require("devtools/client/shared/components/NotificationBox");

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

/**
 * Console root Application component.
 */
class App extends Component {
Beispiel #7
0
  /* eslint-disable complexity */
  /**
   * The inputNode "keypress" event handler.
   *
   * @private
   * @param Event event
   */
  _keyPress(event) {
    let inputNode = this.inputNode;
    let inputValue = this.getInputValue();
    let inputUpdated = false;

    if (event.ctrlKey) {
      switch (event.charCode) {
        case 101:
          // control-e
          if (Services.appinfo.OS == "WINNT") {
            break;
          }
          let lineEndPos = inputValue.length;
          if (this.hasMultilineInput()) {
            // find index of closest newline >= cursor
            for (let i = inputNode.selectionEnd; i < lineEndPos; i++) {
              if (inputValue.charAt(i) == "\r" ||
                  inputValue.charAt(i) == "\n") {
                lineEndPos = i;
                break;
              }
            }
          }
          inputNode.setSelectionRange(lineEndPos, lineEndPos);
          event.preventDefault();
          this.clearCompletion();
          break;

        case 110:
          // Control-N differs from down arrow: it ignores autocomplete state.
          // Note that we preserve the default 'down' navigation within
          // multiline text.
          if (Services.appinfo.OS == "Darwin" &&
              this.canCaretGoNext() &&
              this.historyPeruse(HISTORY_FORWARD)) {
            event.preventDefault();
            // Ctrl-N is also used to focus the Network category button on
            // MacOSX. The preventDefault() call doesn't prevent the focus
            // from moving away from the input.
            this.focus();
          }
          this.clearCompletion();
          break;

        case 112:
          // Control-P differs from up arrow: it ignores autocomplete state.
          // Note that we preserve the default 'up' navigation within
          // multiline text.
          if (Services.appinfo.OS == "Darwin" &&
              this.canCaretGoPrevious() &&
              this.historyPeruse(HISTORY_BACK)) {
            event.preventDefault();
            // Ctrl-P may also be used to focus some category button on MacOSX.
            // The preventDefault() call doesn't prevent the focus from moving
            // away from the input.
            this.focus();
          }
          this.clearCompletion();
          break;
        default:
          break;
      }
      return;
    } else if (event.keyCode == KeyCodes.DOM_VK_RETURN) {
      let autoMultiline = Services.prefs.getBoolPref(PREF_AUTO_MULTILINE);
      if (event.shiftKey ||
          (!Debugger.isCompilableUnit(inputNode.value) && autoMultiline)) {
        // shift return or incomplete statement
        return;
      }
    }

    switch (event.keyCode) {
      case KeyCodes.DOM_VK_ESCAPE:
        if (this.autocompletePopup.isOpen) {
          this.clearCompletion();
          event.preventDefault();
          event.stopPropagation();
        }
        break;

      case KeyCodes.DOM_VK_RETURN:
        if (this._autocompletePopupNavigated &&
            this.autocompletePopup.isOpen &&
            this.autocompletePopup.selectedIndex > -1) {
          this.acceptProposedCompletion();
        } else {
          this.execute();
          this._inputChanged = false;
        }
        event.preventDefault();
        break;

      case KeyCodes.DOM_VK_UP:
        if (this.autocompletePopup.isOpen) {
          inputUpdated = this.complete(this.COMPLETE_BACKWARD);
          if (inputUpdated) {
            this._autocompletePopupNavigated = true;
          }
        } else if (this.canCaretGoPrevious()) {
          inputUpdated = this.historyPeruse(HISTORY_BACK);
        }
        if (inputUpdated) {
          event.preventDefault();
        }
        break;

      case KeyCodes.DOM_VK_DOWN:
        if (this.autocompletePopup.isOpen) {
          inputUpdated = this.complete(this.COMPLETE_FORWARD);
          if (inputUpdated) {
            this._autocompletePopupNavigated = true;
          }
        } else if (this.canCaretGoNext()) {
          inputUpdated = this.historyPeruse(HISTORY_FORWARD);
        }
        if (inputUpdated) {
          event.preventDefault();
        }
        break;

      case KeyCodes.DOM_VK_PAGE_UP:
        if (this.autocompletePopup.isOpen) {
          inputUpdated = this.complete(this.COMPLETE_PAGEUP);
          if (inputUpdated) {
            this._autocompletePopupNavigated = true;
          }
        } else {
          this.hud.outputScroller.scrollTop =
            Math.max(0,
              this.hud.outputScroller.scrollTop -
              this.hud.outputScroller.clientHeight
            );
        }
        event.preventDefault();
        break;

      case KeyCodes.DOM_VK_PAGE_DOWN:
        if (this.autocompletePopup.isOpen) {
          inputUpdated = this.complete(this.COMPLETE_PAGEDOWN);
          if (inputUpdated) {
            this._autocompletePopupNavigated = true;
          }
        } else {
          this.hud.outputScroller.scrollTop =
            Math.min(this.hud.outputScroller.scrollHeight,
              this.hud.outputScroller.scrollTop +
              this.hud.outputScroller.clientHeight
            );
        }
        event.preventDefault();
        break;

      case KeyCodes.DOM_VK_HOME:
        if (this.autocompletePopup.isOpen) {
          this.autocompletePopup.selectedIndex = 0;
          event.preventDefault();
        } else if (inputValue.length <= 0) {
          this.hud.outputScroller.scrollTop = 0;
          event.preventDefault();
        }
        break;

      case KeyCodes.DOM_VK_END:
        if (this.autocompletePopup.isOpen) {
          this.autocompletePopup.selectedIndex =
            this.autocompletePopup.itemCount - 1;
          event.preventDefault();
        } else if (inputValue.length <= 0) {
          this.hud.outputScroller.scrollTop =
            this.hud.outputScroller.scrollHeight;
          event.preventDefault();
        }
        break;

      case KeyCodes.DOM_VK_LEFT:
        if (this.autocompletePopup.isOpen || this.lastCompletion.value) {
          this.clearCompletion();
        }
        break;

      case KeyCodes.DOM_VK_RIGHT:
        let cursorAtTheEnd = this.inputNode.selectionStart ==
                             this.inputNode.selectionEnd &&
                             this.inputNode.selectionStart ==
                             inputValue.length;
        let haveSuggestion = this.autocompletePopup.isOpen ||
                             this.lastCompletion.value;
        let useCompletion = cursorAtTheEnd || this._autocompletePopupNavigated;
        if (haveSuggestion && useCompletion &&
            this.complete(this.COMPLETE_HINT_ONLY) &&
            this.lastCompletion.value &&
            this.acceptProposedCompletion()) {
          event.preventDefault();
        }
        if (this.autocompletePopup.isOpen) {
          this.clearCompletion();
        }
        break;

      case KeyCodes.DOM_VK_TAB:
        // Generate a completion and accept the first proposed value.
        if (this.complete(this.COMPLETE_HINT_ONLY) &&
            this.lastCompletion &&
            this.acceptProposedCompletion()) {
          event.preventDefault();
        } else if (this._inputChanged) {
          this.updateCompleteNode(l10n.getStr("Autocomplete.blank"));
          event.preventDefault();
        }
        break;
      default:
        break;
    }
  }
Beispiel #8
0
function transformConsoleAPICallPacket(packet) {
  const { message } = packet;

  let parameters = message.arguments;
  let type = message.level;
  let level = getLevelFromType(type);
  let messageText = null;
  const timer = message.timer;

  // Special per-type conversion.
  switch (type) {
    case "clear":
      // We show a message to users when calls console.clear() is called.
      parameters = [l10n.getStr("consoleCleared")];
      break;
    case "count":
    case "countReset":
      // Chrome RDP doesn't have a special type for count.
      type = MESSAGE_TYPE.LOG;
      const {counter} = message;

      if (!counter) {
        // We don't show anything if we don't have counter data.
        type = MESSAGE_TYPE.NULL_MESSAGE;
      } else if (counter.error) {
        messageText = l10n.getFormatStr(counter.error, [counter.label]);
        level = MESSAGE_LEVEL.WARN;
        parameters = null;
      } else {
        const label = counter.label ? counter.label : l10n.getStr("noCounterLabel");
        messageText = `${label}: ${counter.count}`;
        parameters = null;
      }
      break;
    case "timeStamp":
      type = MESSAGE_TYPE.NULL_MESSAGE;
      break;
    case "time":
      parameters = null;
      if (timer && timer.error) {
        messageText = l10n.getFormatStr(timer.error, [timer.name]);
        level = MESSAGE_LEVEL.WARN;
      } else {
        // We don't show anything for console.time calls to match Chrome's behaviour.
        type = MESSAGE_TYPE.NULL_MESSAGE;
      }
      break;
    case "timeLog":
    case "timeEnd":
      if (timer && timer.error) {
        parameters = null;
        messageText = l10n.getFormatStr(timer.error, [timer.name]);
        level = MESSAGE_LEVEL.WARN;
      } else if (timer) {
        // We show the duration to users when calls console.timeLog/timeEnd is called,
        // if corresponding console.time() was called before.
        const duration = Math.round(timer.duration * 100) / 100;
        if (type === "timeEnd") {
          messageText = l10n.getFormatStr("console.timeEnd", [timer.name, duration]);
          parameters = null;
        } else if (type === "timeLog") {
          const [, ...rest] = parameters;
          parameters = [
            l10n.getFormatStr("timeLog", [timer.name, duration]),
            ...rest,
          ];
        }
      } else {
        // If the `timer` property does not exists, we don't output anything.
        type = MESSAGE_TYPE.NULL_MESSAGE;
      }
      break;
    case "table":
      const supportedClasses = [
        "Array", "Object", "Map", "Set", "WeakMap", "WeakSet"];
      if (
        !Array.isArray(parameters) ||
        parameters.length === 0 ||
        !supportedClasses.includes(parameters[0].class)
      ) {
        // If the class of the first parameter is not supported,
        // we handle the call as a simple console.log
        type = "log";
      }
      break;
    case "group":
      type = MESSAGE_TYPE.START_GROUP;
      if (parameters.length === 0) {
        parameters = [l10n.getStr("noGroupLabel")];
      }
      break;
    case "groupCollapsed":
      type = MESSAGE_TYPE.START_GROUP_COLLAPSED;
      if (parameters.length === 0) {
        parameters = [l10n.getStr("noGroupLabel")];
      }
      break;
    case "groupEnd":
      type = MESSAGE_TYPE.END_GROUP;
      parameters = null;
      break;
    case "dirxml":
      // Handle console.dirxml calls as simple console.log
      type = "log";
      break;
  }

  const frame = message.filename ? {
    source: message.filename,
    sourceId: message.sourceId,
    line: message.lineNumber,
    column: message.columnNumber,
  } : null;

  return new ConsoleMessage({
    source: MESSAGE_SOURCE.CONSOLE_API,
    type,
    level,
    parameters,
    messageText,
    stacktrace: message.stacktrace ? message.stacktrace : null,
    frame,
    timeStamp: message.timeStamp,
    userProvidedStyles: message.styles,
    prefix: message.prefix,
    private: message.private,
    executionPoint: message.executionPoint,
    logpointId: message.logpointId,
  });
}
Beispiel #9
0
 win.addEventListener("DOMContentLoaded", function () {
     win.document.title = l10n.getStr("browserConsole.title");
   deferred.resolve(win);
 }, {once: true});
Beispiel #10
0
/**
 * Transforms a packet from Firefox RDP structure to Chrome RDP structure.
 */
function transformPacket(packet) {
  if (packet._type) {
    packet = convertCachedPacket(packet);
  }

  switch (packet.type) {
    case "consoleAPICall": {
      let { message } = packet;

      let parameters = message.arguments;
      let type = message.level;
      let level = getLevelFromType(type);
      let messageText = null;
      const timer = message.timer;

      // Special per-type conversion.
      switch (type) {
        case "clear":
          // We show a message to users when calls console.clear() is called.
          parameters = [l10n.getStr("consoleCleared")];
          break;
        case "count":
          // Chrome RDP doesn't have a special type for count.
          type = MESSAGE_TYPE.LOG;
          let {counter} = message;
          let label = counter.label ? counter.label : l10n.getStr("noCounterLabel");
          messageText = `${label}: ${counter.count}`;
          parameters = null;
          break;
        case "time":
          parameters = null;
          if (timer && timer.error) {
            messageText = l10n.getFormatStr(timer.error, [timer.name]);
            level = MESSAGE_LEVEL.WARN;
          } else {
            // We don't show anything for console.time calls to match Chrome's behaviour.
            type = MESSAGE_TYPE.NULL_MESSAGE;
          }
          break;
        case "timeEnd":
          parameters = null;
          if (timer && timer.error) {
            messageText = l10n.getFormatStr(timer.error, [timer.name]);
            level = MESSAGE_LEVEL.WARN;
          } else if (timer) {
            // We show the duration to users when calls console.timeEnd() is called,
            // if corresponding console.time() was called before.
            let duration = Math.round(timer.duration * 100) / 100;
            messageText = l10n.getFormatStr("timeEnd", [timer.name, duration]);
          } else {
            // If the `timer` property does not exists, we don't output anything.
            type = MESSAGE_TYPE.NULL_MESSAGE;
          }
          break;
        case "table":
          const supportedClasses = [
            "Array", "Object", "Map", "Set", "WeakMap", "WeakSet"];
          if (
            !Array.isArray(parameters) ||
            parameters.length === 0 ||
            !supportedClasses.includes(parameters[0].class)
          ) {
            // If the class of the first parameter is not supported,
            // we handle the call as a simple console.log
            type = "log";
          }
          break;
        case "group":
          type = MESSAGE_TYPE.START_GROUP;
          if (parameters.length === 0) {
            parameters = [l10n.getStr("noGroupLabel")];
          }
          break;
        case "groupCollapsed":
          type = MESSAGE_TYPE.START_GROUP_COLLAPSED;
          if (parameters.length === 0) {
            parameters = [l10n.getStr("noGroupLabel")];
          }
          break;
        case "groupEnd":
          type = MESSAGE_TYPE.END_GROUP;
          parameters = null;
          break;
        case "dirxml":
          // Handle console.dirxml calls as simple console.log
          type = "log";
          break;
      }

      const frame = message.filename ? {
        source: message.filename,
        line: message.lineNumber,
        column: message.columnNumber,
      } : null;

      return new ConsoleMessage({
        source: MESSAGE_SOURCE.CONSOLE_API,
        type,
        level,
        parameters,
        messageText,
        stacktrace: message.stacktrace ? message.stacktrace : null,
        frame,
        timeStamp: message.timeStamp,
        userProvidedStyles: message.styles,
      });
    }

    case "navigationMessage": {
      let { message } = packet;
      return new ConsoleMessage({
        source: MESSAGE_SOURCE.CONSOLE_API,
        type: MESSAGE_TYPE.LOG,
        level: MESSAGE_LEVEL.LOG,
        messageText: "Navigated to " + message.url,
        timeStamp: message.timeStamp
      });
    }

    case "logMessage": {
      let { message } = packet;
      return new ConsoleMessage({
        source: MESSAGE_SOURCE.CONSOLE_API,
        type: MESSAGE_TYPE.LOG,
        level: MESSAGE_LEVEL.LOG,
        messageText: message.message,
        timeStamp: message.timeStamp
      });
    }

    case "pageError": {
      let { pageError } = packet;
      let level = MESSAGE_LEVEL.ERROR;
      if (pageError.warning || pageError.strict) {
        level = MESSAGE_LEVEL.WARN;
      } else if (pageError.info) {
        level = MESSAGE_LEVEL.INFO;
      }

      const frame = pageError.sourceName ? {
        source: pageError.sourceName,
        line: pageError.lineNumber,
        column: pageError.columnNumber
      } : null;

      let matchesCSS = /^(?:CSS|Layout)\b/.test(pageError.category);
      let messageSource = matchesCSS ? MESSAGE_SOURCE.CSS
                                     : MESSAGE_SOURCE.JAVASCRIPT;
      return new ConsoleMessage({
        source: messageSource,
        type: MESSAGE_TYPE.LOG,
        level,
        messageText: pageError.errorMessage,
        stacktrace: pageError.stacktrace ? pageError.stacktrace : null,
        frame,
        exceptionDocURL: pageError.exceptionDocURL,
        timeStamp: pageError.timeStamp,
        notes: pageError.notes,
      });
    }

    case "networkEvent": {
      let { networkEvent } = packet;

      return new NetworkEventMessage({
        actor: networkEvent.actor,
        isXHR: networkEvent.isXHR,
        request: networkEvent.request,
        response: networkEvent.response,
        timeStamp: networkEvent.timeStamp,
        totalTime: networkEvent.totalTime,
      });
    }

    case "evaluationResult":
    default: {
      let {
        exceptionMessage: messageText,
        exceptionDocURL,
        frame,
        result: parameters,
        timestamp: timeStamp,
        notes,
      } = packet;

      const level = messageText ? MESSAGE_LEVEL.ERROR : MESSAGE_LEVEL.LOG;
      return new ConsoleMessage({
        source: MESSAGE_SOURCE.JAVASCRIPT,
        type: MESSAGE_TYPE.RESULT,
        level,
        messageText,
        parameters,
        exceptionDocURL,
        frame,
        timeStamp,
        notes,
      });
    }
  }
}