mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	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:
		@@ -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}]
 | 
				
			||||||
@@ -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`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.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 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,3 +1,5 @@
 | 
				
			|||||||
 | 
					/* globals gitGraph */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(document).ready(function () {
 | 
					$(document).ready(function () {
 | 
				
			||||||
	var graphList = [];
 | 
						var 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,17 +930,14 @@ 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 $item = $(item);
 | 
					 | 
				
			||||||
            var addLine = $item.find('span[data-line].add').data("line");
 | 
					            var addLine = $item.find('span[data-line].add').data("line");
 | 
				
			||||||
            var delLine = $item.find('span[data-line].del').data("line");
 | 
					            var delLine = $item.find('span[data-line].del').data("line");
 | 
				
			||||||
            var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;
 | 
					            var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;
 | 
				
			||||||
            $item.find(".bar .add").css("width", addPercent + "%");
 | 
					            $item.find(".bar .add").css("width", addPercent + "%");
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Quick start and repository home
 | 
					    // Quick start and repository home
 | 
				
			||||||
    $('#repo-clone-ssh').click(function () {
 | 
					    $('#repo-clone-ssh').click(function () {
 | 
				
			||||||
@@ -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,7 +1168,6 @@ 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;
 | 
				
			||||||
@@ -1185,7 +1182,6 @@ String.prototype.endsWith = function (pattern) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return pos;
 | 
					    return pos;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
})(jQuery);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
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;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user