--- a/.eslintignore
+++ b/.eslintignore
@@ -96,17 +96,17 @@ devtools/client/shadereditor/**
devtools/client/shared/*.jsm
devtools/client/shared/webgl-utils.js
devtools/client/shared/developer-toolbar.js
devtools/client/shared/components/test/**
devtools/client/shared/redux/middleware/test/**
devtools/client/shared/test/**
!devtools/client/shared/test/test-actor-registry.js
devtools/client/shared/widgets/*.jsm
-devtools/client/sourceeditor/**
+devtools/client/sourceeditor/test/*.js
devtools/client/webaudioeditor/**
devtools/client/webconsole/**
!devtools/client/webconsole/panel.js
!devtools/client/webconsole/jsterm.js
!devtools/client/webconsole/console-commands.js
devtools/client/webide/**
!devtools/client/webide/components/webideCli.js
devtools/server/*.js
new file mode 100644
--- /dev/null
+++ b/devtools/client/sourceeditor/.eslintrc
@@ -0,0 +1,12 @@
+{
+ // Extend from the devtools eslintrc.
+ "extends": "../../.eslintrc",
+
+ "rules": {
+ // The inspector is being migrated to HTML and cleaned of
+ // chrome-privileged code, so this rule disallows requiring chrome
+ // code. Some files here disable this rule still. The
+ // goal is to enable the rule globally on all files.
+ "mozilla/reject-some-requires": [2, "^(chrome|chrome:.*|resource:.*|devtools/server/.*|.*\\.jsm)$"],
+ },
+}
--- a/devtools/client/sourceeditor/autocomplete.js
+++ b/devtools/client/sourceeditor/autocomplete.js
@@ -66,27 +66,27 @@ function initializeAutoCompletion(ctx, o
return tip;
}
});
let keyMap = {};
let updateArgHintsCallback = cm.tern.updateArgHints.bind(cm.tern, cm);
cm.on("cursorActivity", updateArgHintsCallback);
- keyMap[autocompleteKey] = cm => {
- cm.tern.getHint(cm, data => {
+ keyMap[autocompleteKey] = cmArg => {
+ cmArg.tern.getHint(cmArg, data => {
CodeMirror.on(data, "shown", () => ed.emit("before-suggest"));
CodeMirror.on(data, "close", () => ed.emit("after-suggest"));
CodeMirror.on(data, "select", () => ed.emit("suggestion-entered"));
- CodeMirror.showHint(cm, (cm, cb) => cb(data), { async: true });
+ CodeMirror.showHint(cmArg, (cmIgnore, cb) => cb(data), { async: true });
});
};
- keyMap[Editor.keyFor("showInformation2", { noaccel: true })] = cm => {
- cm.tern.showType(cm, null, () => {
+ keyMap[Editor.keyFor("showInformation2", { noaccel: true })] = cmArg => {
+ cmArg.tern.showType(cmArg, null, () => {
ed.emit("show-information");
});
};
cm.addKeyMap(keyMap);
let destroyTern = function () {
ed.off("destroy", destroyTern);
cm.off("cursorActivity", updateArgHintsCallback);
--- a/devtools/client/sourceeditor/css-autocompleter.js
+++ b/devtools/client/sourceeditor/css-autocompleter.js
@@ -1,15 +1,19 @@
/* 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";
+/* eslint-disable complexity */
+
+/* eslint-disable mozilla/reject-some-requires */
const { Cc, Ci } = require("chrome");
+/* eslint-enable mozilla/reject-some-requires */
const {cssTokenizer, cssTokenizerWithLineColumn} = require("devtools/shared/css-parsing-utils");
/**
* Here is what this file (+ css-parsing-utils.js) do.
*
* The main objective here is to provide as much suggestions to the user editing
* a stylesheet in Style Editor. The possible things that can be suggested are:
* - CSS property names
@@ -47,16 +51,17 @@ const {cssTokenizer, cssTokenizerWithLin
* "media" and "keyframes" respectively, although "media" can have suggestions
* like "max-width", "orientation" etc. Similarly "value" state can also have
* much better logical suggestions if we fine grain identify a sub state just
* like we do for the "selector" state.
*/
// Autocompletion types.
+/* eslint-disable no-inline-comments */
const CSS_STATES = {
"null": "null",
property: "property", // foo { bar|: … }
value: "value", // foo {bar: baz|}
selector: "selector", // f| {bar: baz}
media: "media", // @med| , or , @media scr| { }
keyframes: "keyframes", // @keyf|
frame: "frame", // @keyframs foobar { t|
@@ -66,16 +71,17 @@ const SELECTOR_STATES = {
"null": "null",
id: "id", // #f|
class: "class", // #foo.b|
tag: "tag", // fo|
pseudo: "pseudo", // foo:|
attribute: "attribute", // foo[b|
value: "value", // foo[bar=b|
};
+/* eslint-enable no-inline-comments */
const { properties, propertyNames } = getCSSKeywords();
/**
* Constructor for the autocompletion object.
*
* @param options {Object} An options object containing the following options:
* - walker {Object} The object used for query selecting from the current
@@ -974,21 +980,21 @@ CSSCompleter.prototype = {
* the caret.
* - value {string} The css value at the current caret.
* - loc {object} An object containing the starting and the ending
* caret position of the whole selector, value or property.
* - { start: {line, ch}, end: {line, ch}}
*/
getInfoAt: function (source, caret) {
// Limits the input source till the {line, ch} caret position
- function limit(source, {line, ch}) {
+ function limit(sourceArg, {line, ch}) {
line++;
- let list = source.split("\n");
+ let list = sourceArg.split("\n");
if (list.length < line) {
- return source;
+ return sourceArg;
}
if (line == 1) {
return list[0].slice(0, ch);
}
return [...list.slice(0, line - 1),
list[line - 1].slice(0, ch)].join("\n");
}
@@ -1031,21 +1037,21 @@ CSSCompleter.prototype = {
}
// Whitespace cannot change state.
if (token.tokenType == "whitespace") {
prevToken = token;
continue;
}
- let state = this.resolveState(limitedSource, {
+ let forwState = this.resolveState(limitedSource, {
line: line,
ch: token.endOffset + ech
});
- if (check(state)) {
+ if (check(forwState)) {
if (prevToken && prevToken.tokenType == "whitespace") {
token = prevToken;
}
location = {
line: line,
ch: token.startOffset + ech
};
found = true;
@@ -1092,21 +1098,21 @@ CSSCompleter.prototype = {
limitedSource = limitedSource.slice(0, -1 * length);
}
// Whitespace cannot change state.
if (token.tokenType == "whitespace") {
continue;
}
- let state = this.resolveState(limitedSource, {
+ let backState = this.resolveState(limitedSource, {
line: line,
ch: token.startOffset
});
- if (check(state)) {
+ if (check(backState)) {
if (tokens[i + 1] && tokens[i + 1].tokenType == "whitespace") {
token = tokens[i + 1];
}
location = {
line: line,
ch: isValue ? token.endOffset : token.startOffset
};
found = true;
@@ -1121,26 +1127,26 @@ CSSCompleter.prototype = {
return location;
};
if (state == CSS_STATES.selector) {
// For selector state, the ending and starting point of the selector is
// either when the state changes or the selector becomes empty and a
// single selector can span multiple lines.
// Backward loop to determine the beginning location of the selector.
- let start = traverseBackwards(state => {
- return (state != CSS_STATES.selector ||
+ let start = traverseBackwards(backState => {
+ return (backState != CSS_STATES.selector ||
(this.selector == "" && this.selectorBeforeNot == null));
});
line = caret.line;
limitedSource = limit(source, caret);
// Forward loop to determine the ending location of the selector.
- let end = traverseForward(state => {
- return (state != CSS_STATES.selector ||
+ let end = traverseForward(forwState => {
+ return (forwState != CSS_STATES.selector ||
(this.selector == "" && this.selectorBeforeNot == null));
});
// Since we have start and end positions, figure out the whole selector.
let selector = source.split("\n").slice(start.line, end.line + 1);
selector[selector.length - 1] =
selector[selector.length - 1].substring(0, end.ch);
selector[0] = selector[0].substring(start.ch);
@@ -1175,21 +1181,21 @@ CSSCompleter.prototype = {
}
}
};
}
}
} else if (state == CSS_STATES.value) {
// CSS value can be multiline too, so we go forward and backwards to
// determine the bounds of the value at caret
- let start = traverseBackwards(state => state != CSS_STATES.value, true);
+ let start = traverseBackwards(backState => backState != CSS_STATES.value, true);
line = caret.line;
limitedSource = limit(source, caret);
- let end = traverseForward(state => state != CSS_STATES.value);
+ let end = traverseForward(forwState => forwState != CSS_STATES.value);
let value = source.split("\n").slice(start.line, end.line + 1);
value[value.length - 1] = value[value.length - 1].substring(0, end.ch);
value[0] = value[0].substring(start.ch);
value = value.join("\n");
return {
state: state,
propertyName: propertyName,
--- a/devtools/client/sourceeditor/debugger.js
+++ b/devtools/client/sourceeditor/debugger.js
@@ -125,17 +125,17 @@ function hasBreakpoint(ctx, line) {
/**
* Adds a visual breakpoint for a specified line. Third
* parameter 'cond' can hold any object.
*
* After adding a breakpoint, this function makes Editor to
* emit a breakpointAdded event.
*/
function addBreakpoint(ctx, line, cond) {
- function _addBreakpoint(ctx, line, cond) {
+ function _addBreakpoint() {
let { ed, cm } = ctx;
let meta = dbginfo.get(ed);
let info = cm.lineInfo(line);
// The line does not exist in the editor. This is harmless, the
// architecture calling this assumes the editor will handle this
// gracefully, and make sure breakpoints exist when they need to.
if (!info) {
@@ -161,19 +161,19 @@ function addBreakpoint(ctx, line, cond)
if (hasBreakpoint(ctx, line)) {
return null;
}
let deferred = promise.defer();
// If lineInfo() returns null, wait a tick to give the editor a chance to
// initialize properly.
if (ctx.cm.lineInfo(line) === null) {
- DevToolsUtils.executeSoon(() => _addBreakpoint(ctx, line, cond));
+ DevToolsUtils.executeSoon(() => _addBreakpoint());
} else {
- _addBreakpoint(ctx, line, cond);
+ _addBreakpoint();
}
return deferred.promise;
}
/**
* Helps reset the debugger's breakpoint state
* - removes the breakpoints in the editor
* - cleares the debugger's breakpoint state
@@ -216,20 +216,17 @@ function removeBreakpoint(ctx, line) {
meta.breakpoints[info.line] = null;
ed.removeLineClass(info.line, "breakpoint");
ed.removeLineClass(info.line, "conditional");
ed.emit("breakpointRemoved", line);
}
function moveBreakpoint(ctx, fromLine, toLine) {
- let { ed, cm } = ctx;
-
- let fromTop = cm.cursorCoords({ line: fromLine }).top;
- let toTop = cm.cursorCoords({ line: toLine }).top;
+ let { ed } = ctx;
ed.removeBreakpoint(fromLine);
ed.addBreakpoint(toLine);
}
function setBreakpointCondition(ctx, line) {
let { ed, cm } = ctx;
let info = cm.lineInfo(line);
@@ -240,17 +237,17 @@ function setBreakpointCondition(ctx, lin
if (!info) {
return;
}
ed.addLineClass(line, "conditional");
}
function removeBreakpointCondition(ctx, line) {
- let { ed, cm } = ctx;
+ let { ed } = ctx;
ed.removeLineClass(line, "conditional");
}
/**
* Returns a list of all breakpoints in the current Editor.
*/
function getBreakpoints(ctx) {
@@ -329,9 +326,11 @@ function findPrev(ctx, query) {
// Export functions
[
initialize, hasBreakpoint, addBreakpoint, removeBreakpoint, moveBreakpoint,
setBreakpointCondition, removeBreakpointCondition, getBreakpoints, removeBreakpoints,
setDebugLocation, getDebugLocation, clearDebugLocation, find, findNext,
findPrev
-].forEach(func => module.exports[func.name] = func);
+].forEach(func => {
+ module.exports[func.name] = func;
+});
--- a/devtools/client/sourceeditor/editor.js
+++ b/devtools/client/sourceeditor/editor.js
@@ -1,17 +1,19 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
/* vim:set ts=2 sw=2 sts=2 et tw=80:
* 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 { Cu, Cc, Ci } = require("chrome");
+/* eslint-disable mozilla/reject-some-requires */
+const {Cc, Ci} = require("chrome");
+/* eslint-enable mozilla/reject-some-requires */
const {
EXPAND_TAB,
TAB_SIZE,
DETECT_INDENT,
getIndentationFromIteration
} = require("devtools/shared/indentation");
@@ -80,17 +82,18 @@ const CM_SCRIPTS = [
const CM_IFRAME =
"data:text/html;charset=utf8,<!DOCTYPE html>" +
"<html dir='ltr'>" +
" <head>" +
" <style>" +
" html, body { height: 100%; }" +
" body { margin: 0; overflow: hidden; }" +
- " .CodeMirror { width: 100%; height: 100% !important; line-height: 1.25 !important;}" +
+ " .CodeMirror { width: 100%; height: 100% !important; " +
+ "line-height: 1.25 !important;}" +
" </style>" +
CM_STYLES.map(style => "<link rel='stylesheet' href='" + style + "'>").join("\n") +
" </head>" +
" <body class='theme-body devtools-monospace'></body>" +
"</html>";
const CM_MAPPING = [
"focus",
@@ -412,23 +415,23 @@ Editor.prototype = {
this.emit("change");
if (!this._lastDirty) {
this._lastDirty = true;
this.emit("dirty-change");
}
});
cm.on("cursorActivity", () => this.emit("cursorActivity"));
- cm.on("gutterClick", (cm, line, gutter, ev) => {
+ cm.on("gutterClick", (cmArg, line, gutter, ev) => {
let head = { line: line, ch: 0 };
let tail = { line: line, ch: this.getText(line).length };
// Shift-click on a gutter selects the whole line.
if (ev.shiftKey) {
- cm.setSelection(head, tail);
+ cmArg.setSelection(head, tail);
return;
}
this.emit("gutterClick", line, ev.button);
});
win.CodeMirror.defineExtension("l10n", (name) => {
return L10N.GetStringFromName(name);
@@ -817,26 +820,26 @@ Editor.prototype = {
* Handles attaching a set of events listeners on a marker. They should
* be passed as an object literal with keys as event names and values as
* function listeners. The line number, marker node and optional data
* will be passed as arguments to the function listener.
*
* You don't need to worry about removing these event listeners.
* They're automatically orphaned when clearing markers.
*/
- setMarkerListeners: function (line, gutterName, markerClass, events, data) {
+ setMarkerListeners: function (line, gutterName, markerClass, eventsArg, data) {
if (!this.hasMarker(line, gutterName, markerClass)) {
return;
}
let cm = editors.get(this);
let marker = cm.lineInfo(line).gutterMarkers[gutterName];
- for (let name in events) {
- let listener = events[name].bind(this, line, marker, data);
+ for (let name in eventsArg) {
+ let listener = eventsArg[name].bind(this, line, marker, data);
marker.addEventListener(name, listener);
}
},
/**
* Returns whether a line is decorated using the specified class name.
*/
hasLineClass: function (line, className) {
@@ -996,18 +999,18 @@ Editor.prototype = {
inp.selectionStart = inp.selectionEnd = inp.value.length;
}
}
this.openDialog(div, (line) => {
// Handle LINE:COLUMN as well as LINE
let match = line.toString().match(RE_JUMP_TO_LINE);
if (match) {
- let [, line, column ] = match;
- this.setCursor({line: line - 1, ch: column ? column - 1 : 0 });
+ let [, matchLine, column ] = match;
+ this.setCursor({line: matchLine - 1, ch: column ? column - 1 : 0 });
}
});
},
/**
* Moves the content of the current line or the lines selected up a line.
*/
moveLineUp: function () {
@@ -1287,34 +1290,34 @@ function getCSSKeywords() {
for (let i = 0; i < array.length; ++i) {
keys[array[i]] = true;
}
return keys;
}
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
- let cssProperties = domUtils.getCSSPropertyNames(domUtils.INCLUDE_ALIASES);
- let cssColors = {};
- let cssValues = {};
- cssProperties.forEach(property => {
+ let properties = domUtils.getCSSPropertyNames(domUtils.INCLUDE_ALIASES);
+ let colors = {};
+ let values = {};
+ properties.forEach(property => {
if (property.includes("color")) {
domUtils.getCSSValuesForProperty(property).forEach(value => {
- cssColors[value] = true;
+ colors[value] = true;
});
} else {
domUtils.getCSSValuesForProperty(property).forEach(value => {
- cssValues[value] = true;
+ values[value] = true;
});
}
});
return {
- cssProperties: keySet(cssProperties),
- cssValues: cssValues,
- cssColors: cssColors
+ cssProperties: keySet(properties),
+ cssValues: values,
+ cssColors: colors
};
}
/**
* Returns a controller object that can be used for
* editor-specific commands such as find, jump to line,
* copy/paste, etc.
*/