add make targets for js and css, add js linter (#6952)

* add make targets for js,css, add javascript linter

- add `make js`, deprecating `make javascripts`
- add `make css`, deprecating `make generate-stylesheets` and
  `make stylesheets-check`
- changed the unclean css check to only run on CI
- add JS linting via eslint with basic configuration and fixed
  discovered issues
- changed autoprefixer to use official `postcss-cli` avoiding the need
  to loop in the makefile
- moved browserslist to package.json so other future tools can use it
  too.
- update documentation for new make targets and added JS section

* fix indentation

* move functions used in html to 'exported' list

* Run lessc binary without having to install anything to node_modules

* use relative paths to node bin scripts, removing npx

* Revert "use relative paths to node bin scripts, removing npx"

This reverts commit 119b725525.

* fix lessc and postcss plugins

* check for node_modules and use actual bin names
This commit is contained in:
silverwind 2019-05-16 07:57:47 +02:00 committed by Lauris BH
parent 775a5a5b0f
commit d9dcd09340
9 changed files with 891 additions and 132 deletions

View file

@ -50,7 +50,8 @@ pipeline:
pull: true pull: true
commands: commands:
- npm install - npm install
- make stylesheets-check - make css
- make js
when: when:
event: [ push, tag, pull_request ] event: [ push, tag, pull_request ]

25
.eslintrc Normal file
View file

@ -0,0 +1,25 @@
root: true
extends:
- eslint:recommended
parserOptions:
ecmaVersion: 2015
env:
browser: true
jquery: true
es6: true
globals:
Clipboard: false
CodeMirror: false
emojify: false
SimpleMDE: false
Vue: false
Dropzone: false
u2fApi: false
hljs: false
rules:
no-unused-vars: [error, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]

View file

@ -65,9 +65,9 @@ high-level discussions.
## Testing redux ## Testing redux
Before submitting a pull request, run all the tests for the whole tree Before submitting a pull request, run all the tests for the whole tree
to make sure your changes don't cause regression elsewhere. to make sure your changes don't cause regression elsewhere.
Here's how to run the test suite: Here's how to run the test suite:
- Install the correct version of the drone-cli package. As of this - Install the correct version of the drone-cli package. As of this
writing, the correct drone-cli version is writing, the correct drone-cli version is
@ -75,7 +75,7 @@ Here's how to run the test suite:
- Ensure you have enough free disk space. You will need at least - Ensure you have enough free disk space. You will need at least
15-20 Gb of free disk space to hold all of the containers drone 15-20 Gb of free disk space to hold all of the containers drone
creates (a default AWS or GCE disk size won't work -- see creates (a default AWS or GCE disk size won't work -- see
[#6243](https://github.com/go-gitea/gitea/issues/6243)). [#6243](https://github.com/go-gitea/gitea/issues/6243)).
- Change into the base directory of your copy of the gitea repository, - Change into the base directory of your copy of the gitea repository,
and run `drone exec --local --build-event pull_request`. and run `drone exec --local --build-event pull_request`.
@ -114,7 +114,7 @@ Generally, the go build tools are installed as-needed in the `Makefile`.
An exception are the tools to build the CSS and images. An exception are the tools to build the CSS and images.
- To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager) at version 8.0 or above - To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager) at version 8.0 or above
with `npm` and then run `npm install` and `make generate-stylesheets`. with `npm` and then run `npm install` and `make css`.
- To build Images: ImageMagick, inkscape and zopflipng binaries must be - To build Images: ImageMagick, inkscape and zopflipng binaries must be
available in your `PATH` to run `make generate-images`. available in your `PATH` to run `make generate-images`.
@ -214,7 +214,7 @@ to the maintainers team. If a maintainer is inactive for more than 3
months and forgets to leave the maintainers team, the owners may move months and forgets to leave the maintainers team, the owners may move
him or her from the maintainers team to the advisors team. him or her from the maintainers team to the advisors team.
For security reasons, Maintainers should use 2FA for their accounts and For security reasons, Maintainers should use 2FA for their accounts and
if possible provide gpg signed commits. if possible provide gpg signed commits.
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/ https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
https://help.github.com/articles/signing-commits-with-gpg/ https://help.github.com/articles/signing-commits-with-gpg/
@ -281,7 +281,7 @@ be reviewed by two maintainers and must pass the automatic tests.
* Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`. * Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`.
* When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin` * When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin`
* If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged. * If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged.
* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`. * Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.) * And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.)
* If needed send PR for changelog on branch `master`. * If needed send PR for changelog on branch `master`.
* Send PR to [blog repository](https://github.com/go-gitea/blog) announcing the release. * Send PR to [blog repository](https://github.com/go-gitea/blog) announcing the release.

View file

@ -365,33 +365,55 @@ release-compress:
fi fi
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done; cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
.PHONY: javascripts .PHONY: js
javascripts: public/js/index.js js:
@if ([ ! -d "$(PWD)/node_modules" ]); then \
.IGNORE: public/js/index.js echo "node_modules directory is absent, please run 'npm install' first"; \
public/js/index.js: $(JAVASCRIPTS)
cat $< >| $@
.PHONY: stylesheets-check
stylesheets-check: generate-stylesheets
@diff=$$(git diff public/css/*); \
if [ -n "$$diff" ]; then \
echo "Please run 'make generate-stylesheets' and commit the result:"; \
echo "$${diff}"; \
exit 1; \ exit 1; \
fi; fi;
.PHONY: generate-stylesheets
generate-stylesheets:
@hash npx > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash npx > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
echo "Please install npm version 5.2+"; \ echo "Please install npm version 5.2+"; \
exit 1; \ exit 1; \
fi; fi;
$(eval BROWSERS := "> 1%, last 2 firefox versions, last 2 safari versions, ie 11") npx eslint public/js
npx lesshint public/less/
.PHONY: css
css:
@if ([ ! -d "$(PWD)/node_modules" ]); then \
echo "node_modules directory is absent, please run 'npm install' first"; \
exit 1; \
fi;
@hash npx > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
echo "Please install npm version 5.2+"; \
exit 1; \
fi;
npx lesshint public/less/
npx lessc --clean-css="--s0 -b" public/less/index.less public/css/index.css npx lessc --clean-css="--s0 -b" public/less/index.less public/css/index.css
$(foreach file, $(filter-out public/less/themes/_base.less, $(wildcard public/less/themes/*)),npx lessc --clean-css="--s0 -b" public/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;) $(foreach file, $(filter-out public/less/themes/_base.less, $(wildcard public/less/themes/*)),npx lessc --clean-css="--s0 -b" public/less/themes/$(notdir $(file)) > public/css/theme-$(notdir $(call strip-suffix,$(file))).css;)
$(foreach file, $(wildcard public/css/*),npx postcss --use autoprefixer --autoprefixer.browsers $(BROWSERS) -o $(file) $(file);) npx postcss --use autoprefixer --no-map --replace public/css/*
@diff=$$(git diff public/css/*); \
if ([ ! -z "$CI" ] && [ -n "$$diff" ]); then \
echo "Generated files in public/css have changed, please commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
.PHONY: javascripts
javascripts:
echo "'make javascripts' is deprecated, please use 'make js'"
$(MAKE) js
.PHONY: stylesheets-check
stylesheets-check:
echo "'make stylesheets-check' is deprecated, please use 'make css'"
$(MAKE) css
.PHONY: generate-stylesheets
generate-stylesheets:
echo "'make generate-stylesheets' is deprecated, please use 'make css'"
$(MAKE) css
.PHONY: swagger-ui .PHONY: swagger-ui
swagger-ui: swagger-ui:

View file

@ -136,30 +136,36 @@ You should lint, vet and spell-check with:
make vet lint misspell-check make vet lint misspell-check
``` ```
### Updating the stylesheets ### Updating CSS
To generate the stylsheets, you will need [Node.js](https://nodejs.org/) at version 8.0 or above. To generate the CSS, you will need [Node.js](https://nodejs.org/) 8.0 or greater and the build dependencies:
At present we use [less](http://lesscss.org/) and [postcss](https://postcss.org) to generate our stylesheets. Do
**not** edit the files in `public/css/` directly, as they are generated from
`lessc` from the files in `public/less/`.
If you wish to work on the stylesheets, you will need to install `lessc` the
less compiler and `postcss`. The recommended way to do this is using `npm install`:
```bash ```bash
cd "$GOPATH/src/code.gitea.io/gitea"
npm install npm install
``` ```
You can then edit the less stylesheets and regenerate the stylesheets using: At present we use [less](http://lesscss.org/) and [postcss](https://postcss.org) to generate our CSS. Do
**not** edit the files in `public/css` directly, as they are generated from `lessc` from the files in `public/less`.
Edit files in `public/less`, run the linter, regenerate the CSS and commit all changed files:
```bash ```bash
make generate-stylesheets make css
``` ```
You should commit both the changes to the css and the less files when making ### Updating JS
PRs.
To run the JavaScript linter you will need [Node.js](https://nodejs.org/) 8.0 or greater and the build dependencies:
```bash
npm install
```
Edit files in `public/js` and run the linter:
```bash
make js
```
### Updating the API ### Updating the API

728
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,16 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"autoprefixer": "9.5.1", "autoprefixer": "9.5.1",
"eslint": "5.16.0",
"less": "3.9.0", "less": "3.9.0",
"less-plugin-clean-css": "1.5.1", "less-plugin-clean-css": "1.5.1",
"lesshint": "^6.3.6", "lesshint": "^6.3.6",
"postcss-cli-simple": "3.0.0" "postcss-cli": "6.1.2"
} },
"browserslist": [
"> 1%",
"last 2 firefox versions",
"last 2 safari versions",
"ie 11"
]
} }

View file

@ -1,13 +1,15 @@
/* globals gitGraph */
$(document).ready(function () { $(document).ready(function () {
var graphList = []; var graphList = [];
if (!document.getElementById('graph-canvas')) { if (!document.getElementById('graph-canvas')) {
return; return;
} }
$("#graph-raw-list li span.node-relation").each(function () { $("#graph-raw-list li span.node-relation").each(function () {
graphList.push($(this).text()); graphList.push($(this).text());
}) })
gitGraph(document.getElementById('graph-canvas'), graphList); gitGraph(document.getElementById('graph-canvas'), graphList);
}) })

View file

@ -1,3 +1,6 @@
/* globals wipPrefixes, issuesTribute, emojiTribute */
/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */
/* exported toggleDeadlineForm, setDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */
'use strict'; 'use strict';
function htmlEncode(text) { function htmlEncode(text) {
@ -89,7 +92,7 @@ if (!Array.from) {
if (typeof Object.assign != 'function') { if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true // Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", { Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2 value: function assign(target, _varArgs) { // .length of function is 2
'use strict'; 'use strict';
if (target == null) { // TypeError if undefined or null if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object'); throw new TypeError('Cannot convert undefined or null to object');
@ -131,8 +134,8 @@ function initCommentPreviewTab($form) {
var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]');
$previewPanel.html(data); $previewPanel.html(data);
emojify.run($previewPanel[0]); emojify.run($previewPanel[0]);
$('pre code', $previewPanel[0]).each(function (i, block) { $('pre code', $previewPanel[0]).each(function () {
hljs.highlightBlock(block); hljs.highlightBlock(this);
}); });
} }
); );
@ -161,8 +164,8 @@ function initEditPreviewTab($form) {
var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]');
$previewPanel.html(data); $previewPanel.html(data);
emojify.run($previewPanel[0]); emojify.run($previewPanel[0]);
$('pre code', $previewPanel[0]).each(function (i, block) { $('pre code', $previewPanel[0]).each(function () {
hljs.highlightBlock(block); hljs.highlightBlock(this);
}); });
} }
); );
@ -355,7 +358,8 @@ function reload() {
} }
function initImagePaste(target) { function initImagePaste(target) {
target.each(function(i, field) { target.each(function() {
var field = this;
field.addEventListener('paste', function(event){ field.addEventListener('paste', function(event){
retrieveImageFromClipboardAsBlob(event, function(img) { retrieveImageFromClipboardAsBlob(event, function(img) {
var name = img.name.substr(0, img.name.lastIndexOf('.')); var name = img.name.substr(0, img.name.lastIndexOf('.'));
@ -606,7 +610,7 @@ function initInstall() {
$('#sql_settings').show(); $('#sql_settings').show();
$('#pgsql_settings').toggle(dbType === "PostgreSQL"); $('#pgsql_settings').toggle(dbType === "PostgreSQL");
$.each(dbDefaults, function(type, defaultHost) { $.each(dbDefaults, function(_type, defaultHost) {
if ($('#db_host').val() == defaultHost) { if ($('#db_host').val() == defaultHost) {
$('#db_host').val(dbDefaults[dbType]); $('#db_host').val(dbDefaults[dbType]);
return false; return false;
@ -636,8 +640,7 @@ function initInstall() {
}); });
$('#enable-openid-signin input').change(function () { $('#enable-openid-signin input').change(function () {
if ($(this).is(':checked')) { if ($(this).is(':checked')) {
if ( $('#disable-registration input').is(':checked') ) { if (!$('#disable-registration input').is(':checked')) {
} else {
$('#enable-openid-signup').checkbox('check'); $('#enable-openid-signup').checkbox('check');
} }
} else { } else {
@ -669,7 +672,7 @@ function initRepository() {
$dropdown.dropdown({ $dropdown.dropdown({
fullTextSearch: true, fullTextSearch: true,
selectOnKeydown: false, selectOnKeydown: false,
onChange: function (text, value, $choice) { onChange: function (_text, _value, $choice) {
if ($choice.data('url')) { if ($choice.data('url')) {
window.location.href = $choice.data('url'); window.location.href = $choice.data('url');
} }
@ -756,9 +759,6 @@ function initRepository() {
} }
// Milestones // Milestones
if ($('.repository.milestones').length > 0) {
}
if ($('.repository.new.milestone').length > 0) { if ($('.repository.new.milestone').length > 0) {
var $datepicker = $('.milestone.datepicker'); var $datepicker = $('.milestone.datepicker');
$datepicker.datetimepicker({ $datepicker.datetimepicker({
@ -857,8 +857,8 @@ function initRepository() {
} else { } else {
$renderContent.html(data.content); $renderContent.html(data.content);
emojify.run($renderContent[0]); emojify.run($renderContent[0]);
$('pre code', $renderContent[0]).each(function (i, block) { $('pre code', $renderContent[0]).each(function () {
hljs.highlightBlock(block); hljs.highlightBlock(this);
}); });
} }
}); });
@ -912,7 +912,7 @@ function initRepository() {
$(this).parent().hide(); $(this).parent().hide();
}); });
$('.merge-button > .dropdown').dropdown({ $('.merge-button > .dropdown').dropdown({
onChange: function (text, value, $choice) { onChange: function (_text, _value, $choice) {
if ($choice.data('do')) { if ($choice.data('do')) {
$mergeButton.find('.button-text').text($choice.text()); $mergeButton.find('.button-text').text($choice.text());
$mergeButton.data('do', $choice.data('do')); $mergeButton.data('do', $choice.data('do'));
@ -930,16 +930,13 @@ function initRepository() {
// Diff // Diff
if ($('.repository.diff').length > 0) { if ($('.repository.diff').length > 0) {
var $counter = $('.diff-counter'); $('.diff-counter').each(function () {
if ($counter.length >= 1) { var $item = $(this);
$counter.each(function (i, item) { var addLine = $item.find('span[data-line].add').data("line");
var $item = $(item); var delLine = $item.find('span[data-line].del').data("line");
var addLine = $item.find('span[data-line].add').data("line"); var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;
var delLine = $item.find('span[data-line].del').data("line"); $item.find(".bar .add").css("width", addPercent + "%");
var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100; });
$item.find(".bar .add").css("width", addPercent + "%");
});
}
} }
// Quick start and repository home // Quick start and repository home
@ -982,7 +979,7 @@ function initRepository() {
var toggleMigrations = function(){ var toggleMigrations = function(){
var authUserName = $('#auth_username').val(); var authUserName = $('#auth_username').val();
var cloneAddr = $('#clone_addr').val(); var cloneAddr = $('#clone_addr').val();
if (!$('#mirror').is(":checked") && (authUserName!=undefined && authUserName.length > 0) if (!$('#mirror').is(":checked") && (authUserName!=undefined && authUserName.length > 0)
&& (cloneAddr!=undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com")))) { && (cloneAddr!=undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com")))) {
$('#migrate_items').show(); $('#migrate_items').show();
} else { } else {
@ -1085,8 +1082,9 @@ function assingMenuAttributes(menu) {
var id = Math.floor(Math.random() * Math.floor(1000000)); var id = Math.floor(Math.random() * Math.floor(1000000));
menu.attr('data-write', menu.attr('data-write') + id); menu.attr('data-write', menu.attr('data-write') + id);
menu.attr('data-preview', menu.attr('data-preview') + id); menu.attr('data-preview', menu.attr('data-preview') + id);
menu.find('.item').each(function(i, item) { menu.find('.item').each(function() {
$(item).attr('data-tab', $(item).attr('data-tab') + id); var tab = $(this).attr('data-tab') + id;
$(this).attr('data-tab', tab);
}); });
menu.parent().find("*[data-tab='write']").attr('data-tab', 'write' + id); menu.parent().find("*[data-tab='write']").attr('data-tab', 'write' + id);
menu.parent().find("*[data-tab='preview']").attr('data-tab', 'preview' + id); menu.parent().find("*[data-tab='preview']").attr('data-tab', 'preview' + id);
@ -1170,22 +1168,20 @@ String.prototype.endsWith = function (pattern) {
}; };
// Adding function to get the cursor position in a text field to jQuery object. // Adding function to get the cursor position in a text field to jQuery object.
(function ($, undefined) { $.fn.getCursorPosition = function () {
$.fn.getCursorPosition = function () { var el = $(this).get(0);
var el = $(this).get(0); var pos = 0;
var pos = 0; if ('selectionStart' in el) {
if ('selectionStart' in el) { pos = el.selectionStart;
pos = el.selectionStart; } else if ('selection' in document) {
} else if ('selection' in document) { el.focus();
el.focus(); var Sel = document.selection.createRange();
var Sel = document.selection.createRange(); var SelLength = document.selection.createRange().text.length;
var SelLength = document.selection.createRange().text.length; Sel.moveStart('character', -el.value.length);
Sel.moveStart('character', -el.value.length); pos = Sel.text.length - SelLength;
pos = Sel.text.length - SelLength;
}
return pos;
} }
})(jQuery); return pos;
}
function setSimpleMDE($editArea) { function setSimpleMDE($editArea) {
if (codeMirrorEditor) { if (codeMirrorEditor) {
@ -1249,7 +1245,7 @@ function setCodeMirror($editArea) {
codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], { codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], {
lineNumbers: true lineNumbers: true
}); });
codeMirrorEditor.on("change", function (cm, change) { codeMirrorEditor.on("change", function (cm, _change) {
$editArea.val(cm.getValue()); $editArea.val(cm.getValue());
}); });
@ -1271,10 +1267,13 @@ function initEditor() {
$editFilename.keyup(function (e) { $editFilename.keyup(function (e) {
var $section = $('.breadcrumb span.section'); var $section = $('.breadcrumb span.section');
var $divider = $('.breadcrumb div.divider'); var $divider = $('.breadcrumb div.divider');
var value;
var parts;
if (e.keyCode == 8) { if (e.keyCode == 8) {
if ($(this).getCursorPosition() == 0) { if ($(this).getCursorPosition() == 0) {
if ($section.length > 0) { if ($section.length > 0) {
var value = $section.last().find('a').text(); value = $section.last().find('a').text();
$(this).val(value + $(this).val()); $(this).val(value + $(this).val());
$(this)[0].setSelectionRange(value.length, value.length); $(this)[0].setSelectionRange(value.length, value.length);
$section.last().remove(); $section.last().remove();
@ -1283,9 +1282,9 @@ function initEditor() {
} }
} }
if (e.keyCode == 191) { if (e.keyCode == 191) {
var parts = $(this).val().split('/'); parts = $(this).val().split('/');
for (var i = 0; i < parts.length; ++i) { for (var i = 0; i < parts.length; ++i) {
var value = parts[i]; value = parts[i];
if (i < parts.length - 1) { if (i < parts.length - 1) {
if (value.length) { if (value.length) {
$('<span class="section"><a href="#">' + value + '</a></span>').insertBefore($(this)); $('<span class="section"><a href="#">' + value + '</a></span>').insertBefore($(this));
@ -1298,9 +1297,9 @@ function initEditor() {
$(this)[0].setSelectionRange(0, 0); $(this)[0].setSelectionRange(0, 0);
} }
} }
var parts = []; parts = [];
$('.breadcrumb span.section').each(function (i, element) { $('.breadcrumb span.section').each(function () {
element = $(element); var element = $(this);
if (element.find('a').length) { if (element.find('a').length) {
parts.push(element.find('a').text()); parts.push(element.find('a').text());
} else { } else {
@ -1319,10 +1318,11 @@ function initEditor() {
var markdownFileExts = $editArea.data("markdown-file-exts").split(","); var markdownFileExts = $editArea.data("markdown-file-exts").split(",");
var lineWrapExtensions = $editArea.data("line-wrap-extensions").split(","); var lineWrapExtensions = $editArea.data("line-wrap-extensions").split(",");
$editFilename.on("keyup", function (e) { $editFilename.on("keyup", function () {
var val = $editFilename.val(), m, mode, spec, extension, extWithDot, previewLink, dataUrl, apiCall; var val = $editFilename.val(), m, mode, spec, extension, extWithDot, previewLink, dataUrl, apiCall;
extension = extWithDot = ""; extension = extWithDot = "";
if (m = /.+\.([^.]+)$/.exec(val)) { m = /.+\.([^.]+)$/.exec(val);
if (m) {
extension = m[1]; extension = m[1];
extWithDot = "." + extension; extWithDot = "." + extension;
} }
@ -1684,15 +1684,6 @@ function buttonsClickOnEnter() {
}); });
} }
function hideWhenLostFocus(body, parent) {
$(document).click(function (e) {
var target = e.target;
if (!$(target).is(body) && !$(target).parents().is(parent)) {
$(body).hide();
}
});
}
function searchUsers() { function searchUsers() {
var $searchUserBox = $('#search-user-box'); var $searchUserBox = $('#search-user-box');
$searchUserBox.search({ $searchUserBox.search({
@ -1701,7 +1692,7 @@ function searchUsers() {
url: suburl + '/api/v1/users/search?q={query}', url: suburl + '/api/v1/users/search?q={query}',
onResponse: function(response) { onResponse: function(response) {
var items = []; var items = [];
$.each(response.data, function (i, item) { $.each(response.data, function (_i, item) {
var title = item.login; var title = item.login;
if (item.full_name && item.full_name.length > 0) { if (item.full_name && item.full_name.length > 0) {
title += ' (' + htmlEncode(item.full_name) + ')'; title += ' (' + htmlEncode(item.full_name) + ')';
@ -1728,7 +1719,7 @@ function searchRepositories() {
url: suburl + '/api/v1/repos/search?q={query}&uid=' + $searchRepoBox.data('uid'), url: suburl + '/api/v1/repos/search?q={query}&uid=' + $searchRepoBox.data('uid'),
onResponse: function(response) { onResponse: function(response) {
var items = []; var items = [];
$.each(response.data, function (i, item) { $.each(response.data, function (_i, item) {
items.push({ items.push({
title: item.full_name.split("/")[1], title: item.full_name.split("/")[1],
description: item.full_name description: item.full_name
@ -1752,8 +1743,8 @@ function initCodeView() {
deSelect(); deSelect();
}); });
$(window).on('hashchange', function (e) { $(window).on('hashchange', function () {
var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/); var m = window.location.hash.match(/^#(L\d+)-(L\d+)$/);
var $list = $('.code-view ol.linenums > li'); var $list = $('.code-view ol.linenums > li');
var $first; var $first;
if (m) { if (m) {
@ -1803,7 +1794,7 @@ function u2fSigned(resp) {
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
}).done(function(res){ }).done(function(res){
window.location.replace(res); window.location.replace(res);
}).fail(function (xhr, textStatus) { }).fail(function () {
u2fError(1); u2fError(1);
}); });
} }
@ -1821,7 +1812,7 @@ function u2fRegistered(resp) {
success: function(){ success: function(){
reload(); reload();
}, },
fail: function (xhr, textStatus) { fail: function () {
u2fError(1); u2fError(1);
} }
}); });
@ -1889,7 +1880,7 @@ function u2fRegisterRequest() {
} }
u2fError(reason.metaData.code); u2fError(reason.metaData.code);
}); });
}).fail(function(xhr, status, error) { }).fail(function(xhr) {
if(xhr.status === 409) { if(xhr.status === 409) {
$("#nickname").closest("div.field").addClass("error"); $("#nickname").closest("div.field").addClass("error");
} }
@ -1962,7 +1953,7 @@ $(document).ready(function () {
}); });
// make table <tr> element clickable like a link // make table <tr> element clickable like a link
$('tr[data-href]').click(function(event) { $('tr[data-href]').click(function() {
window.location = $(this).data('href'); window.location = $(this).data('href');
}); });
@ -2388,7 +2379,7 @@ function initVueComponents(){
var searchedURL = this.searchURL; var searchedURL = this.searchURL;
var searchedQuery = this.searchQuery; var searchedQuery = this.searchQuery;
$.getJSON(searchedURL, function(result, textStatus, request) { $.getJSON(searchedURL, function(result, _textStatus, request) {
if (searchedURL == self.searchURL) { if (searchedURL == self.searchURL) {
self.repos = result.data; self.repos = result.data;
var count = request.getResponseHeader('X-Total-Count'); var count = request.getResponseHeader('X-Total-Count');
@ -2446,6 +2437,7 @@ function initVueApp() {
}, },
}); });
} }
function timeAddManual() { function timeAddManual() {
$('.mini.modal') $('.mini.modal')
.modal({ .modal({
@ -2796,7 +2788,7 @@ function initTopicbar() {
$.post(saveBtn.data('link'), { $.post(saveBtn.data('link'), {
"_csrf": csrf, "_csrf": csrf,
"topics": topics "topics": topics
}, function(data, textStatus, xhr){ }, function(_data, _textStatus, xhr){
if (xhr.responseJSON.status === 'ok') { if (xhr.responseJSON.status === 'ok') {
viewDiv.children(".topic").remove(); viewDiv.children(".topic").remove();
if (topics.length) { if (topics.length) {
@ -2873,14 +2865,14 @@ function initTopicbar() {
this.attr("data-value", value).contents().first().replaceWith(value); this.attr("data-value", value).contents().first().replaceWith(value);
return $(this); return $(this);
}, },
onAdd: function(addedValue, addedText, $addedChoice) { onAdd: function(addedValue, _addedText, $addedChoice) {
addedValue = addedValue.toLowerCase().trim(); addedValue = addedValue.toLowerCase().trim();
$($addedChoice).attr('data-value', addedValue); $($addedChoice).attr('data-value', addedValue);
$($addedChoice).attr('data-text', addedValue); $($addedChoice).attr('data-text', addedValue);
} }
}); });
$.fn.form.settings.rules.validateTopic = function(values, regExp) { $.fn.form.settings.rules.validateTopic = function(_values, regExp) {
var topics = topicDropdown.children('a.ui.label'), var topics = topicDropdown.children('a.ui.label'),
status = topics.length === 0 || topics.last().attr("data-value").match(regExp); status = topics.length === 0 || topics.last().attr("data-value").match(regExp);
if (!status) { if (!status) {
@ -2981,7 +2973,7 @@ function initIssueList() {
var filteredResponse = {'success': true, 'results': []}; var filteredResponse = {'success': true, 'results': []};
var currIssueId = $('#new-dependency-drop-list').data('issue-id'); var currIssueId = $('#new-dependency-drop-list').data('issue-id');
// Parse the response from the api to work with our dropdown // Parse the response from the api to work with our dropdown
$.each(response, function(index, issue) { $.each(response, function(_i, issue) {
// Don't list current issue in the dependency list. // Don't list current issue in the dependency list.
if(issue.id === currIssueId) { if(issue.id === currIssueId) {
return; return;