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 119b725525a8430b32ee7a6e6009b4ece544e39b. * fix lessc and postcss plugins * check for node_modules and use actual bin names
This commit is contained in:
		
							parent
							
								
									775a5a5b0f
								
							
						
					
					
						commit
						d9dcd09340
					
				
					 9 changed files with 891 additions and 132 deletions
				
			
		|  | @ -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
									
								
							
							
						
						
									
										25
									
								
								.eslintrc
									
									
									
									
									
										Normal 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}] | ||||||
|  | @ -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. | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								Makefile
									
									
									
									
									
								
							|  | @ -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: | ||||||
|  |  | ||||||
|  | @ -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
									
									
									
								
							
							
						
						
									
										728
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							|  | @ -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" | ||||||
|  |   ] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue