From a1f0679f3aa13dd3e36145c47f3a8a3a3c4c1a17 Mon Sep 17 00:00:00 2001 From: Sofiya Semenova Date: Tue, 28 Nov 2017 16:42:24 -0500 Subject: [PATCH] Educator 1552 - Implement roving tabindex for WYSIWYG editor for discussions --- common/static/common/js/discussion/utils.js | 35 ++++ .../views/discussion_thread_view.js | 5 +- .../js/discussion/views/new_post_view.js | 5 +- lms/static/js/Markdown.Editor.js | 174 +++++++++--------- scripts/all-tests.sh | 2 +- 5 files changed, 131 insertions(+), 90 deletions(-) diff --git a/common/static/common/js/discussion/utils.js b/common/static/common/js/discussion/utils.js index ea0088dac4..b7af3dc425 100644 --- a/common/static/common/js/discussion/utils.js +++ b/common/static/common/js/discussion/utils.js @@ -7,6 +7,9 @@ DiscussionUtil.wmdEditors = {}; + DiscussionUtil.leftKey = 37; + DiscussionUtil.rightKey = 39; + DiscussionUtil.getTemplate = function(id) { return $('script#' + id).html(); }; @@ -539,6 +542,38 @@ }; }; + DiscussionUtil.handleKeypressInToolbar = function(event) { + var $currentButton, $nextButton, $toolbar, $allButtons, + keyPressed, nextIndex, currentButtonIndex, + validKeyPress, toolbarHasButtons; + + $currentButton = $(event.target); + keyPressed = event.which || event.keyCode; + $toolbar = $currentButton.parent(); + $allButtons = $toolbar.children('.wmd-button'); + + validKeyPress = keyPressed === this.leftKey || keyPressed === this.rightKey; + toolbarHasButtons = $allButtons.length > 0; + + if (validKeyPress && toolbarHasButtons) { + currentButtonIndex = $allButtons.index($currentButton); + nextIndex = keyPressed === this.leftKey ? currentButtonIndex - 1 : currentButtonIndex + 1; + nextIndex = Math.max(Math.min(nextIndex, $allButtons.length - 1), 0); + + $nextButton = $($allButtons[nextIndex]); + this.moveSelectionToNextItem($currentButton, $nextButton); + } + }; + + DiscussionUtil.moveSelectionToNextItem = function(prevItem, nextItem) { + prevItem.attr('aria-selected', 'false'); + prevItem.attr('tabindex', '-1'); + + nextItem.attr('aria-selected', 'true'); + nextItem.attr('tabindex', '0'); + nextItem.focus(); + }; + return DiscussionUtil; }).call(this); }).call(window); diff --git a/common/static/common/js/discussion/views/discussion_thread_view.js b/common/static/common/js/discussion/views/discussion_thread_view.js index 11405cd0ff..77fd92258c 100644 --- a/common/static/common/js/discussion/views/discussion_thread_view.js +++ b/common/static/common/js/discussion/views/discussion_thread_view.js @@ -62,7 +62,10 @@ DiscussionThreadView.prototype.events = { 'click .discussion-submit-post': 'submitComment', - 'click .add-response-btn': 'scrollToAddResponse' + 'click .add-response-btn': 'scrollToAddResponse', + 'keydown .wmd-button': function(event) { + return DiscussionUtil.handleKeypressInToolbar(event); + } }; DiscussionThreadView.prototype.$ = function(selector) { diff --git a/common/static/common/js/discussion/views/new_post_view.js b/common/static/common/js/discussion/views/new_post_view.js index 163dba051a..9667eff8aa 100644 --- a/common/static/common/js/discussion/views/new_post_view.js +++ b/common/static/common/js/discussion/views/new_post_view.js @@ -137,7 +137,10 @@ 'change .post-option-input': 'postOptionChange', 'click .cancel': 'cancel', 'click .add-post-cancel': 'cancel', - 'reset .forum-new-post-form': 'updateStyles' + 'reset .forum-new-post-form': 'updateStyles', + 'keydown .wmd-button': function(event) { + return DiscussionUtil.handleKeypressInToolbar(event); + } }; NewPostView.prototype.toggleGroupDropdown = function($target) { diff --git a/lms/static/js/Markdown.Editor.js b/lms/static/js/Markdown.Editor.js index 2111efa6c3..945aa87575 100644 --- a/lms/static/js/Markdown.Editor.js +++ b/lms/static/js/Markdown.Editor.js @@ -1,6 +1,6 @@ // needs Markdown.Converter.js at the moment -(function() { +(function() { var util = {}, position = {}, ui = {}, @@ -62,7 +62,7 @@ // - getConverter() returns the markdown converter object that was passed to the constructor // - run() actually starts the editor; should be called after all necessary plugins are registered. Calling this more than once is a no-op. // - refreshPreview() forces the preview to be updated. This method is only available after run() was called. - Markdown.Editor = function(markdownConverter, idPostfix, help, imageUploadHandler) { + Markdown.Editor = function(markdownConverter, idPostfix, help, imageUploadHandler) { idPostfix = idPostfix || ''; var hooks = this.hooks = new Markdown.HookCollection(); @@ -107,7 +107,7 @@ var forceRefresh = that.refreshPreview = function() { previewManager.refresh(true); }; forceRefresh(); - }; + }; }; // before: contains all the text in the input box BEFORE the selection. @@ -116,11 +116,11 @@ // startRegex: a regular expression to find the start tag // endRegex: a regular expresssion to find the end tag - Chunks.prototype.findTags = function(startRegex, endRegex) { + Chunks.prototype.findTags = function(startRegex, endRegex) { var chunkObj = this; var regex; - if (startRegex) { + if (startRegex) { regex = util.extendRegExp(startRegex, '', '$'); this.before = this.before.replace(regex, @@ -138,7 +138,7 @@ }); } - if (endRegex) { + if (endRegex) { regex = util.extendRegExp(endRegex, '', '$'); this.selection = this.selection.replace(regex, @@ -174,7 +174,7 @@ }; - Chunks.prototype.skipLines = function(nLinesBefore, nLinesAfter, findExtraNewlines) { + Chunks.prototype.skipLines = function(nLinesBefore, nLinesAfter, findExtraNewlines) { if (nLinesBefore === undefined) { nLinesBefore = 1; } @@ -205,7 +205,7 @@ this.endTag = this.endTag.replace(/(\n*$)/, ''); this.after = this.after + re.$1; - if (this.before) { + if (this.before) { regexText = replacementText = ''; while (nLinesBefore--) { @@ -219,7 +219,7 @@ this.before = this.before.replace(new re(regexText + '$', ''), replacementText); } - if (this.after) { + if (this.after) { regexText = replacementText = ''; while (nLinesAfter--) { @@ -264,7 +264,7 @@ // Returns true if the DOM element is visible, false if it's hidden. // Checks if display is anything other than none. - util.isVisible = function(elem) { + util.isVisible = function(elem) { if (window.getComputedStyle) { // Most browsers return window.getComputedStyle(elem, null).getPropertyValue('display') !== 'none'; @@ -318,7 +318,7 @@ // The flags are unchanged. // // regex is a RegExp, pre and post are strings. - util.extendRegExp = function(regex, pre, post) { + util.extendRegExp = function(regex, pre, post) { if (pre === null || pre === undefined) { pre = ''; } @@ -363,7 +363,7 @@ return elem.offsetWidth || elem.scrollWidth; }; - position.getPageSize = function() { + position.getPageSize = function() { var scrollWidth, scrollHeight; var innerWidth, innerHeight; @@ -404,7 +404,7 @@ // Handles pushing and popping TextareaStates for undo/redo commands. // I should rename the stack variables to list. - function UndoManager(callback, panels) { + function UndoManager(callback, panels) { var undoObj = this; var undoStack = []; // A stack of undo states var stackPtr = 0; // The index of the current state @@ -453,7 +453,7 @@ }; // Removes the last state and restores it. - this.undo = function() { + this.undo = function() { if (undoObj.canUndo()) { if (lastState) { // What about setting state -1 to null or checking for undefined? @@ -476,8 +476,8 @@ }; // Redo an action. - this.redo = function() { - if (undoObj.canRedo()) { + this.redo = function() { + if (undoObj.canRedo()) { undoStack[++stackPtr].restore(); if (callback) { @@ -516,10 +516,10 @@ } }; - var handleCtrlYZ = function(event) { + var handleCtrlYZ = function(event) { var handled = false; - if (event.ctrlKey || event.metaKey) { + if (event.ctrlKey || event.metaKey) { // IE and Opera do not support charCode. var keyCode = event.charCode || event.keyCode; var keyCodeChar = String.fromCharCode(keyCode); @@ -555,8 +555,8 @@ }; // Set the mode depending on what is going on in the input area. - var handleModeChange = function(event) { - if (!event.ctrlKey && !event.metaKey) { + var handleModeChange = function(event) { + if (!event.ctrlKey && !event.metaKey) { var keyCode = event.keyCode; if ((keyCode >= 33 && keyCode <= 40) || (keyCode >= 63232 && keyCode <= 63235)) { @@ -630,7 +630,7 @@ // The input textarea state/contents. // This is used to implement undo/redo by the undo manager. - function TextareaState(panels, isInitialState) { + function TextareaState(panels, isInitialState) { // Aliases var stateObj = this; var inputArea = panels.input; @@ -646,23 +646,23 @@ this.scrollTop = inputArea.scrollTop; if (!this.text && inputArea.selectionStart || inputArea.selectionStart === 0) { this.text = inputArea.value; - } + } }; // Sets the selected text in the input box after we've performed an // operation. - this.setInputAreaSelection = function() { + this.setInputAreaSelection = function() { if (!util.isVisible(inputArea)) { return; } - if (inputArea.selectionStart !== undefined && !uaSniffed.isOpera) { + if (inputArea.selectionStart !== undefined && !uaSniffed.isOpera) { inputArea.focus(); inputArea.selectionStart = stateObj.start; inputArea.selectionEnd = stateObj.end; inputArea.scrollTop = stateObj.scrollTop; } - else if (doc.selection) { + else if (doc.selection) { if (doc.activeElement && doc.activeElement !== inputArea) { return; } @@ -677,12 +677,12 @@ } }; - this.setInputAreaSelectionStartEnd = function() { - if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) { + this.setInputAreaSelectionStartEnd = function() { + if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) { stateObj.start = inputArea.selectionStart; stateObj.end = inputArea.selectionEnd; } - else if (doc.selection) { + else if (doc.selection) { stateObj.text = util.fixEolChars(inputArea.value); // IE loses the selection in the textarea when buttons are @@ -723,7 +723,7 @@ }; // Restore this state into the input area. - this.restore = function() { + this.restore = function() { if (stateObj.text != undefined && stateObj.text != inputArea.value) { inputArea.value = stateObj.text; } @@ -732,7 +732,7 @@ }; // Gets a collection of HTML chunks from the inptut textarea. - this.getChunks = function() { + this.getChunks = function() { var chunk = new Chunks(); chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start)); chunk.startTag = ''; @@ -745,7 +745,7 @@ }; // Sets the TextareaState properties given a chunk of markdown. - this.setChunks = function(chunk) { + this.setChunks = function(chunk) { chunk.before = chunk.before + chunk.startTag; chunk.after = chunk.endTag + chunk.after; @@ -757,7 +757,7 @@ this.init(); } - function PreviewManager(converter, panels, previewPushCallback) { + function PreviewManager(converter, panels, previewPushCallback) { var managerObj = this; var timeout; var elapsedTime; @@ -766,7 +766,7 @@ var startType = 'delayed'; // The other legal value is "manual" // Adds event listeners to elements - var setupEvents = function(inputElem, listener) { + var setupEvents = function(inputElem, listener) { util.addEvent(inputElem, 'input', listener); inputElem.onpaste = listener; inputElem.ondrop = listener; @@ -775,7 +775,7 @@ util.addEvent(inputElem, 'keydown', listener); }; - var getDocScrollTop = function() { + var getDocScrollTop = function() { var result = 0; if (window.innerHeight) { @@ -793,7 +793,7 @@ return result; }; - var makePreviewHtml = function() { + var makePreviewHtml = function() { // If there is no registered preview panel // there is nothing to do. if (!panels.preview) @@ -821,13 +821,13 @@ }; // setTimeout is already used. Used as an event listener. - var applyTimeout = function() { + var applyTimeout = function() { if (timeout) { clearTimeout(timeout); timeout = undefined; } - if (startType !== 'manual') { + if (startType !== 'manual') { var delay = 0; if (startType === 'delayed') { @@ -854,7 +854,7 @@ } }; - this.refresh = function(requiresRefresh) { + this.refresh = function(requiresRefresh) { if (requiresRefresh) { oldInputText = ''; makePreviewHtml(); @@ -904,7 +904,7 @@ } }; - var pushPreviewHtml = function(text) { + var pushPreviewHtml = function(text) { var emptyTop = position.getTop(panels.input) - getDocScrollTop(); if (panels.preview) { @@ -930,7 +930,7 @@ } }; - var init = function() { + var init = function() { setupEvents(panels.input, applyTimeout); makePreviewHtml(); @@ -946,7 +946,7 @@ // And download dialog // Most of this has been moved to CSS but the div creation and // browser-specific hacks remain here. - ui.createBackground = function() { + ui.createBackground = function() { var background = doc.createElement('div'), style = background.style; @@ -999,7 +999,7 @@ defaultInputText, callback, imageIsDecorativeLabel, - imageUploadHandler) { + imageUploadHandler) { // These variables need to be declared at this level since they are used // in multiple functions. var dialog, // The dialog box. @@ -1108,7 +1108,7 @@ imageIsDecorativeLabel: imageIsDecorativeLabel, imageUploadHandler: imageUploadHandler }); - dialog.setAttribute('dir', doc.head.getAttribute('dir')); + dialog.setAttribute('dir', doc.head.getAttribute('dir')); dialog.setAttribute('role', 'dialog'); dialog.setAttribute('tabindex', '-1'); dialog.setAttribute('aria-labelledby', 'editorDialogTitle'); @@ -1184,7 +1184,7 @@ // Why is this in a zero-length timeout? // Is it working around a browser bug? - setTimeout(function() { + setTimeout(function() { createDialog(); var defTextLen = defaultInputText.length; @@ -1204,7 +1204,7 @@ }, 0); }; - function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, imageUploadHandler) { + function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, imageUploadHandler) { var inputBox = panels.input, buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements. @@ -1215,9 +1215,9 @@ keyEvent = 'keypress'; } - util.addEvent(inputBox, keyEvent, function(key) { + util.addEvent(inputBox, keyEvent, function(key) { // Check to see if we have a button key and, if so execute the callback. - if ((key.ctrlKey || key.metaKey) && !key.altKey && !key.shiftKey) { + if ((key.ctrlKey || key.metaKey) && !key.altKey && !key.shiftKey) { var keyCode = key.charCode || key.keyCode; var keyCodeStr = String.fromCharCode(keyCode).toLowerCase(); @@ -1303,10 +1303,10 @@ // Perform the button's action. - function doClick(button) { + function doClick(button) { inputBox.focus(); - if (button.textOp) { + if (button.textOp) { if (undoManager) { undoManager.setCommandMode(); } @@ -1336,7 +1336,7 @@ // Yes this is awkward and I think it sucks, but there's // no real workaround. Only the image and link code // create dialogs and require the function pointers. - var fixupInputArea = function() { + var fixupInputArea = function() { inputBox.focus(); if (chunks) { @@ -1351,7 +1351,7 @@ if (!noCleanup) { fixupInputArea(); - } + } } if (button.execute) { @@ -1359,7 +1359,7 @@ } } - function setupButton(button, isEnabled) { + function setupButton(button, isEnabled) { var normalYShift = '0px'; var disabledYShift = '-20px'; var highlightYShift = '-40px'; @@ -1429,7 +1429,7 @@ return function() { method.apply(commandManager, arguments); }; } - function makeSpritedButtonRow() { + function makeSpritedButtonRow() { var buttonBar = panels.buttonBar; var normalYShift = '0px'; @@ -1442,9 +1442,9 @@ buttonRow.className = 'wmd-button-row'; buttonRow = buttonBar.appendChild(buttonRow); var xPosition = 0; - var makeButton = function(id, title, XShift, textOp) { + var makeButton = function(id, title, XShift, textOp, tabIndex) { var button = document.createElement('button'); - button.tabIndex = 0; + button.tabIndex = tabIndex; button.className = 'wmd-button'; button.style.left = xPosition + 'px'; xPosition += 25; @@ -1468,35 +1468,35 @@ xPosition += 25; }; - buttons.bold = makeButton('wmd-bold-button', gettext('Bold (Ctrl+B)'), '0px', bindCommand('doBold')); - buttons.italic = makeButton('wmd-italic-button', gettext('Italic (Ctrl+I)'), '-20px', bindCommand('doItalic')); + buttons.bold = makeButton('wmd-bold-button', gettext('Bold (Ctrl+B)'), '0px', bindCommand('doBold'), 0); + buttons.italic = makeButton('wmd-italic-button', gettext('Italic (Ctrl+I)'), '-20px', bindCommand('doItalic'), -1); makeSpacer(1); buttons.link = makeButton('wmd-link-button', gettext('Hyperlink (Ctrl+L)'), '-40px', bindCommand(function(chunk, postProcessing) { return this.doLinkOrImage(chunk, postProcessing, false); - })); - buttons.quote = makeButton('wmd-quote-button', gettext('Blockquote (Ctrl+Q)'), '-60px', bindCommand('doBlockquote')); - buttons.code = makeButton('wmd-code-button', gettext('Code Sample (Ctrl+K)'), '-80px', bindCommand('doCode')); + }), -1); + buttons.quote = makeButton('wmd-quote-button', gettext('Blockquote (Ctrl+Q)'), '-60px', bindCommand('doBlockquote'), -1); + buttons.code = makeButton('wmd-code-button', gettext('Code Sample (Ctrl+K)'), '-80px', bindCommand('doCode'), -1); buttons.image = makeButton('wmd-image-button', gettext('Image (Ctrl+G)'), '-100px', bindCommand(function(chunk, postProcessing) { return this.doLinkOrImage(chunk, postProcessing, true, imageUploadHandler); - })); + }), -1); makeSpacer(2); buttons.olist = makeButton('wmd-olist-button', gettext('Numbered List (Ctrl+O)'), '-120px', bindCommand(function(chunk, postProcessing) { this.doList(chunk, postProcessing, true); - })); + }), -1); buttons.ulist = makeButton('wmd-ulist-button', gettext('Bulleted List (Ctrl+U)'), '-140px', bindCommand(function(chunk, postProcessing) { this.doList(chunk, postProcessing, false); - })); - buttons.heading = makeButton('wmd-heading-button', gettext('Heading (Ctrl+H)'), '-160px', bindCommand('doHeading')); - buttons.hr = makeButton('wmd-hr-button', gettext('Horizontal Rule (Ctrl+R)'), '-180px', bindCommand('doHorizontalRule')); + }), -1); + buttons.heading = makeButton('wmd-heading-button', gettext('Heading (Ctrl+H)'), '-160px', bindCommand('doHeading'), -1); + buttons.hr = makeButton('wmd-hr-button', gettext('Horizontal Rule (Ctrl+R)'), '-180px', bindCommand('doHorizontalRule'), -1); makeSpacer(3); - buttons.undo = makeButton('wmd-undo-button', gettext('Undo (Ctrl+Z)'), '-200px', null); + buttons.undo = makeButton('wmd-undo-button', gettext('Undo (Ctrl+Z)'), '-200px', null, -1); buttons.undo.execute = function(manager) { if (manager) manager.undo(); }; var redoTitle = /win/.test(nav.platform.toLowerCase()) ? gettext('Redo (Ctrl+Y)') : gettext('Redo (Ctrl+Shift+Z)'); // mac and other non-Windows platforms - buttons.redo = makeButton('wmd-redo-button', redoTitle, '-220px', null); + buttons.redo = makeButton('wmd-redo-button', redoTitle, '-220px', null, -1); buttons.redo.execute = function(manager) { if (manager) manager.redo(); }; if (helpOptions) { @@ -1526,7 +1526,7 @@ } } - this.setUndoRedoButtonStates = setUndoRedoButtonStates; + this.setUndoRedoButtonStates = setUndoRedoButtonStates; } function CommandManager(pluginHooks) { @@ -1570,7 +1570,7 @@ // chunk: The selected region that will be enclosed with */** // nStars: 1 for italics, 2 for bold // insertText: If you just click the button without highlighting text, this gets inserted - commandProto.doBorI = function(chunk, postProcessing, nStars, insertText) { + commandProto.doBorI = function(chunk, postProcessing, nStars, insertText) { // Get rid of whitespace and fixup newlines. chunk.trimWhitespace(); chunk.selection = chunk.selection.replace(/\n{2,}/g, '\n'); @@ -1595,7 +1595,7 @@ var whitespace = re.$1; chunk.before = chunk.before + starsAfter + whitespace; } - else { + else { // In most cases, if you don't have any selected text and click the button // you'll get a selected, marked up region with the default text inserted. if (!chunk.selection && !starsAfter) { @@ -1611,7 +1611,7 @@ return; }; - commandProto.stripLinkDefs = function(text, defsToAdd) { + commandProto.stripLinkDefs = function(text, defsToAdd) { text = text.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm, function(totalMatch, id, link, newlines, title) { defsToAdd[id] = totalMatch.replace(/\s*$/, ''); @@ -1626,7 +1626,7 @@ return text; }; - commandProto.addLinkDef = function(chunk, linkDef) { + commandProto.addLinkDef = function(chunk, linkDef) { var refNumber = 0; // The current reference number var defsToAdd = {}; // // Start with a clean slate by removing all previous link definitions. @@ -1707,12 +1707,12 @@ chunk.findTags(/\s*!?\[/, /\][ ]?(?:\n[ ]*)?(\[.*?\])?/); var background; - if (chunk.endTag.length > 1 && chunk.startTag.length > 0) { + if (chunk.endTag.length > 1 && chunk.startTag.length > 0) { chunk.startTag = chunk.startTag.replace(/!?\[/, ''); chunk.endTag = ''; - this.addLinkDef(chunk, null); + this.addLinkDef(chunk, null); } - else { + else { // We're moving start and end tag back into the selection, since (as we're in the else block) we're not // *removing* a link, but *adding* one, so whatever findTags() found is now back to being part of the // link text. linkEnteredCallback takes care of escaping any brackets. @@ -1808,7 +1808,7 @@ // When making a list, hitting shift-enter will put your cursor on the next line // at the current indent level. - commandProto.doAutoindent = function(chunk, postProcessing) { + commandProto.doAutoindent = function(chunk, postProcessing) { var commandMgr = this, fakeSelection = false; @@ -1850,7 +1850,7 @@ } }; - commandProto.doBlockquote = function(chunk, postProcessing) { + commandProto.doBlockquote = function(chunk, postProcessing) { chunk.selection = chunk.selection.replace(/^(\n*)([^\r]+?)(\n*)$/, function(totalMatch, newlinesBefore, text, newlinesAfter) { chunk.before += newlinesBefore; @@ -1945,7 +1945,7 @@ } ); - var replaceBlanksInTags = function(useBracket) { + var replaceBlanksInTags = function(useBracket) { var replacement = useBracket ? '> ' : ''; if (chunk.startTag) { @@ -1992,13 +1992,13 @@ } }; - commandProto.doCode = function(chunk, postProcessing) { + commandProto.doCode = function(chunk, postProcessing) { var hasTextBefore = /\S[ ]*$/.test(chunk.before); var hasTextAfter = /^[ ]*\S/.test(chunk.after); // Use 'four space' markdown if the selection is on its own // line or is multiline. - if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) { + if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) { chunk.before = chunk.before.replace(/[ ]{4}$/, function(totalMatch) { chunk.selection = totalMatch + chunk.selection; @@ -2055,7 +2055,7 @@ } }; - commandProto.doList = function(chunk, postProcessing, isNumberedList) { + commandProto.doList = function(chunk, postProcessing, isNumberedList) { // These are identical except at the very beginning and end. // Should probably use the regex extension function to make this clearer. var previousItemsRegex = /(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/; @@ -2083,7 +2083,7 @@ }; // Fixes the prefixes of the other list items. - var getPrefixedItem = function(itemText) { + var getPrefixedItem = function(itemText) { // The numbering flag is unset when called by autoindent. if (isNumberedList === undefined) { isNumberedList = /^\s*\d/.test(itemText); @@ -2105,7 +2105,7 @@ chunk.startTag = ''; } - if (chunk.startTag) { + if (chunk.startTag) { var hasDigits = /\d+[.]/.test(chunk.startTag); chunk.startTag = ''; chunk.selection = chunk.selection.replace(/\n[ ]{4}/g, '\n'); @@ -2151,10 +2151,10 @@ chunk.startTag = prefix; var spaces = prefix.replace(/./g, ' '); this.wrap(chunk, SETTINGS.lineLength - spaces.length); - chunk.selection = chunk.selection.replace(/\n/g, '\n' + spaces); + chunk.selection = chunk.selection.replace(/\n/g, '\n' + spaces); }; - commandProto.doHeading = function(chunk, postProcessing) { + commandProto.doHeading = function(chunk, postProcessing) { // Remove leading/trailing whitespace and reduce internal spaces to single spaces. chunk.selection = chunk.selection.replace(/\s+/g, ' '); chunk.selection = chunk.selection.replace(/(^\s+|\s+$)/g, ''); @@ -2196,7 +2196,7 @@ // If it's already a level 1 header, it's removed. var headerLevelToCreate = headerLevel == 0 ? 2 : headerLevel - 1; - if (headerLevelToCreate > 0) { + if (headerLevelToCreate > 0) { // The button only creates level 1 and 2 underline headers. // Why not have it iterate over hash header levels? Wouldn't that be easier and cleaner? var headerChar = headerLevelToCreate >= 2 ? '-' : '='; @@ -2215,5 +2215,5 @@ chunk.startTag = '----------\n'; chunk.selection = ''; chunk.skipLines(2, 1, true); - }; + }; })(); diff --git a/scripts/all-tests.sh b/scripts/all-tests.sh index 730d75dc09..861b7b3e70 100755 --- a/scripts/all-tests.sh +++ b/scripts/all-tests.sh @@ -13,7 +13,7 @@ set -e # Violations thresholds for failing the build export LOWER_PYLINT_THRESHOLD=1000 export UPPER_PYLINT_THRESHOLD=5900 -export ESLINT_THRESHOLD=9134 +export ESLINT_THRESHOLD=9543 export STYLELINT_THRESHOLD=973 XSSLINT_THRESHOLDS=`cat scripts/xsslint_thresholds.json`