diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..fa31fcbec
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,16 @@
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+
+[*.{html,js,css,scss,xml}]
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.yml]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3afe0f014..6b12680ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,11 @@
###############
.idea
log
-upload
+jsp/upload
+php/upload
+net/upload
+asp/upload
+node/upload
###############
@@ -164,7 +168,7 @@ Desktop.ini
dist
eggs
parts
-bin
+# bin
var
sdist
develop-eggs
diff --git a/Gruntfile.js b/Gruntfile.js
index da90a8508..6a2d90c75 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,244 +1,303 @@
-'use strict';
-
-module.exports = function ( grunt ) {
-
- var fs = require("fs"),
- Util = {
-
- jsBasePath: '_src/',
- parseBasePath: '_parse/',
- cssBasePath: 'themes/default/_css/',
-
- fetchScripts: function ( readFile, basePath) {
-
- var sources = fs.readFileSync( readFile );
- sources = /\[([^\]]+\.js'[^\]]+)\]/.exec( sources );
- sources = sources[1].replace( /\/\/.*\n/g, '\n' ).replace( /'|"|\n|\t|\s/g, '' );
- sources = sources.split( "," );
- sources.forEach( function ( filepath, index ) {
- sources[ index ] = basePath + filepath;
- } );
-
- return sources;
- },
-
- fetchStyles: function () {
-
- var sources = fs.readFileSync( this.cssBasePath + "ueditor.css" ),
- filepath = null,
- pattern = /@import\s+([^;]+)*;/g,
- src = [];
-
- while ( filepath = pattern.exec( sources ) ) {
- src.push( this.cssBasePath + filepath[ 1 ].replace( /'|"/g, "" ) );
- }
-
- return src;
-
- }
+"use strict";
+
+module.exports = function(grunt) {
+ var fs = require("fs"),
+ Util = {
+ jsBasePath: "_src/",
+ parseBasePath: "_parse/",
+ cssBasePath: "themes/default/_css/",
+
+ fetchScripts: function(readFile, basePath) {
+ var sources = fs.readFileSync(readFile);
+ sources = /\[([^\]]+\.js'[^\]]+)\]/.exec(sources);
+ sources = sources[1]
+ .replace(/\/\/.*\n/g, "\n")
+ .replace(/'|"|\n|\t|\s/g, "");
+ sources = sources.split(",");
+ sources.forEach(function(filepath, index) {
+ sources[index] = basePath + filepath;
+ });
+
+ return sources;
+ },
+
+ fetchStyles: function() {
+ var sources = fs.readFileSync(this.cssBasePath + "ueditor.css"),
+ filepath = null,
+ pattern = /@import\s+([^;]+)*;/g,
+ src = [];
+
+ while ((filepath = pattern.exec(sources))) {
+ src.push(this.cssBasePath + filepath[1].replace(/'|"/g, ""));
+ }
+ return src;
+ }
+ },
+ packageJson = grunt.file.readJSON("package.json"),
+ server = grunt.option("server") || "php",
+ encode = grunt.option("encode") || "utf8",
+ disDir = "dist/",
+ banner =
+ "/*!\n * " +
+ packageJson.name +
+ "\n * version: " +
+ packageJson.version +
+ "\n * build: <%= new Date() %>\n */\n\n";
+
+ //init
+ (function() {
+ server = typeof server === "string" ? server.toLowerCase() : "php";
+ encode = typeof encode === "string" ? encode.toLowerCase() : "utf8";
+
+ disDir = "dist/" + encode + "-" + server + "/";
+ })();
+
+ grunt.initConfig({
+ pkg: packageJson,
+ concat: {
+ js: {
+ options: {
+ banner: "/*!\n * " +
+ packageJson.name +
+ "\n * version: " +
+ packageJson.version +
+ "\n * build: <%= new Date() %>\n */\n\n" +
+ "(function(){\n\n",
+ footer: "\n\n})();\n",
+ process: function(src, s) {
+ var filename = s.substr(s.indexOf("/") + 1);
+ return (
+ "// " + filename + "\n" + src.replace("/_css/", "/css/") + "\n"
+ );
+ }
},
- server = grunt.option('server') || 'php',
- encode = grunt.option('encode') || 'utf8',
- disDir = "dist/",
- banner = '/*!\n * UEditor\n * version: <%= pkg.version %>\n * build: <%= new Date() %>\n */\n\n';
-
- //init
- ( function () {
-
- server = typeof server === "string" ? server.toLowerCase() : 'php';
- encode = typeof encode === "string" ? encode.toLowerCase() : 'utf8';
-
- disDir = 'dist/' + encode + '-' + server + '/';
-
- } )();
-
- grunt.initConfig( {
- pkg: grunt.file.readJSON('package.json'),
- concat: {
- js: {
- options: {
- banner: banner + '(function(){\n\n',
- footer: '\n\n})()',
- process: function(src) {
- return src.replace('/_css/', '/css/');
- }
- },
- src: Util.fetchScripts( "_examples/editor_api.js", Util.jsBasePath ),
- dest: disDir + '<%= pkg.name %>.all.js'
- },
- parse: {
- options: {
- banner: banner + '(function(){\n\n',
- footer: '\n\n})()'
- },
- src: Util.fetchScripts( "ueditor.parse.js", Util.parseBasePath ),
- dest: disDir + '<%= pkg.name %>.parse.js'
- },
- css: {
- src: Util.fetchStyles(),
- dest: disDir + 'themes/default/css/ueditor.css'
- }
- },
- cssmin: {
- options: {
- banner: banner
- },
- files: {
- expand: true,
- cwd: disDir + 'themes/default/css/',
- src: ['*.css', '!*.min.css'],
- dest: disDir + 'themes/default/css/',
- ext: '.min.css'
- }
+ src: Util.fetchScripts("_examples/editor_api.js", Util.jsBasePath),
+ dest: disDir + packageJson.name + ".all.js"
+ },
+ parse: {
+ options: {
+ banner: "/*!\n * " +
+ packageJson.name +
+ " parse\n * version: " +
+ packageJson.version +
+ "\n * build: <%= new Date() %>\n */\n\n" +
+ "(function(){\n\n",
+ footer: "\n\n})();\n"
},
- gcc: {
- dist: {
- src: disDir + '<%= pkg.name %>.all.js',
- dest: disDir + '<%= pkg.name %>.all.min.js'
- },
- parse: {
- src: disDir + '<%= pkg.name %>.parse.js',
- dest: disDir + '<%= pkg.name %>.parse.min.js'
- }
+ src: Util.fetchScripts("ueditor.parse.js", Util.parseBasePath),
+ dest: disDir + packageJson.name + ".parse.js"
+ },
+ css: {
+ src: Util.fetchStyles(),
+ dest: disDir + "themes/default/css/ueditor.css"
+ }
+ },
+ cssmin: {
+ options: {
+ banner: banner
+ },
+ files: {
+ expand: true,
+ cwd: disDir + "themes/default/css/",
+ src: ["*.css", "!*.min.css"],
+ dest: disDir + "themes/default/css/",
+ ext: ".min.css"
+ }
+ },
+ uglify: {
+ dist: {
+ options: {
+ banner: "/*!\n * " +
+ packageJson.name +
+ "\n * version: " +
+ packageJson.version +
+ "\n * build: <%= new Date() %>\n */"
},
- copy: {
- base: {
- files: [
- {
-
- src: [ '*.html', 'themes/iframe.css', 'themes/default/dialogbase.css', 'themes/default/images/**', 'dialogs/**', 'lang/**', 'third-party/**' ],
- dest: disDir
-
- }
- ]
- },
- demo: {
- files: [
- {
- src: '_examples/completeDemo.html',
- dest: disDir + 'index.html'
- }
- ]
- },
- php: {
-
- expand: true,
- src: 'php/**',
- dest: disDir
-
- },
- asp: {
-
- expand: true,
- src: 'asp/**',
- dest: disDir
-
- },
- jsp: {
-
- expand: true,
- src: 'jsp/**',
- dest: disDir
-
- },
- net: {
-
- expand: true,
- src: 'net/**',
- dest: disDir
-
- }
+ src: disDir + "<%= pkg.name %>.all.js",
+ dest: disDir + "<%= pkg.name %>.all.min.js"
+ },
+ parse: {
+ options: {
+ banner: "/*!\n * " +
+ packageJson.name +
+ " parse\n * version: " +
+ packageJson.version +
+ "\n * build: <%= new Date() %>\n */"
},
- transcoding: {
-
- options: {
- charset: encode
- },
- src: [disDir + '**/*.html', disDir + '**/*.js', disDir + '**/*.css', disDir + '**/*.jsp', disDir + '**/*.java', disDir + '**/*.php', disDir + '**/*.asp', disDir + '**/*.ashx', disDir + '**/*.cs']
-
- },
- replace: {
-
- fileEncode: {
- src: [ disDir+'**/*.html', disDir+'**/*.css', disDir+'**/*.php', disDir+'**/*.jsp', disDir+'**/*.net', disDir+'**/*.asp' ],
- overwrite: true,
- replacements: [ {
- from: /utf-8/gi,
- to: 'gbk'
- } ]
- },
- demo:{
- src: disDir+'index.html',
- overwrite: true,
- replacements: [ {
- from: /\.\.\//gi,
- to: ''
- },{
- from: 'editor_api.js',
- to: '<%= pkg.name %>.all.min.js'
- } ]
- },
- gbkasp:{
-
- src: [ disDir+'asp/*.asp' ],
- overwrite: true,
- replacements: [ {
- from: /65001/gi,
- to: '936'
- } ]
- }
-
- }
-
- } );
-
- grunt.loadNpmTasks('grunt-text-replace');
- grunt.loadNpmTasks('grunt-contrib-concat');
- grunt.loadNpmTasks('grunt-contrib-cssmin');
- grunt.loadNpmTasks('grunt-gcc');
- grunt.loadNpmTasks('grunt-contrib-copy');
- grunt.loadNpmTasks('grunt-transcoding');
-
- grunt.registerTask('default', 'UEditor build', function () {
-
- var tasks = [ 'concat', 'cssmin', 'gcc', 'copy:base', 'copy:'+server, 'copy:demo', 'replace:demo' ];
-
- if ( encode === 'gbk' ) {
- tasks.push( 'replace:fileEncode' );
- if(server === 'asp') {
- tasks.push( 'replace:gbkasp' );
- }
- }
-
- tasks.push( 'transcoding' );
-
- //config修改
- updateConfigFile();
-
- grunt.task.run( tasks );
-
- } );
-
-
- function updateConfigFile () {
+ src: disDir + "<%= pkg.name %>.parse.js",
+ dest: disDir + "<%= pkg.name %>.parse.min.js"
+ }
+ },
+ copy: {
+ base: {
+ files: [
+ {
+ src: [
+ "*.html",
+ "themes/iframe.css",
+ "themes/default/dialogbase.css",
+ "themes/default/images/**",
+ "dialogs/**",
+ "lang/**",
+ "third-party/**"
+ ],
+ dest: disDir
+ }
+ ]
+ },
+ demo: {
+ files: [
+ {
+ src: "_examples/completeDemo.html",
+ dest: disDir + "index.html"
+ }
+ ]
+ },
+ php: {
+ expand: true,
+ src: "php/**",
+ dest: disDir
+ },
+ asp: {
+ expand: true,
+ src: "asp/**",
+ dest: disDir
+ },
+ jsp: {
+ expand: true,
+ src: "jsp/**",
+ dest: disDir
+ },
+ net: {
+ expand: true,
+ src: "net/**",
+ dest: disDir
+ }
+ },
+ transcoding: {
+ options: {
+ charset: encode
+ },
+ src: [
+ disDir + "**/*.html",
+ disDir + "**/*.js",
+ disDir + "**/*.css",
+ disDir + "**/*.json",
+ disDir + "**/*.jsp",
+ disDir + "**/*.asp"
+ ]
+ },
+ replace: {
+ fileEncode: {
+ src: [
+ disDir + "**/*.html",
+ disDir + "dialogs/**/*.js",
+ disDir + "**/*.css",
+ disDir + "**/*.php",
+ disDir + "**/*.jsp",
+ disDir + "**/*.ashx",
+ disDir + "**/*.asp"
+ ],
+ overwrite: true,
+ replacements: [
+ {
+ from: /utf-8/gi,
+ to: "gbk"
+ }
+ ]
+ },
+ demo: {
+ src: disDir + "index.html",
+ overwrite: true,
+ replacements: [
+ {
+ from: /\.\.\//gi,
+ to: ""
+ },
+ {
+ from: "editor_api.js",
+ to: packageJson.name + ".all.min.js"
+ }
+ ]
+ },
+ gbkasp: {
+ src: [disDir + "asp/*.asp"],
+ overwrite: true,
+ replacements: [
+ {
+ from: /65001/gi,
+ to: "936"
+ }
+ ]
+ }
+ },
+ clean: {
+ build: {
+ src: [
+ disDir + "jsp/src",
+ disDir + "*/upload",
+ disDir + ".DS_Store",
+ disDir + "**/.DS_Store",
+ disDir + ".git",
+ disDir + "**/.git"
+ ]
+ }
+ }
+ });
+
+ grunt.loadNpmTasks("grunt-text-replace");
+ grunt.loadNpmTasks("grunt-contrib-concat");
+ grunt.loadNpmTasks("grunt-contrib-cssmin");
+ grunt.loadNpmTasks("grunt-contrib-uglify");
+ grunt.loadNpmTasks("grunt-contrib-copy");
+ grunt.loadNpmTasks("grunt-transcoding");
+ grunt.loadNpmTasks("grunt-contrib-clean");
+
+ grunt.registerTask("default", "UEditor build", function() {
+ var tasks = [
+ "concat",
+ "cssmin",
+ "uglify",
+ "copy:base",
+ "copy:" + server,
+ "copy:demo",
+ "replace:demo",
+ "clean"
+ ];
+
+ if (encode === "gbk") {
+ tasks.push("replace:fileEncode");
+ if (server === "asp") {
+ tasks.push("replace:gbkasp");
+ }
+ }
- var filename = 'ueditor.config.js',
- file = grunt.file.read( filename ),
- path = server + "/",
- suffix = server === "net" ? ".ashx" : "."+server;
+ tasks.push("transcoding");
- file = file.replace( /php\//ig, path ).replace( /\.php/ig, suffix );
+ //config修改
+ updateConfigFile();
- //写入到dist
- if ( grunt.file.write( disDir + filename, file ) ) {
+ grunt.task.run(tasks);
+ });
- grunt.log.writeln( 'config file update success' );
+ function updateConfigFile() {
+ var filename = "ueditor.config.js",
+ file = grunt.file.read(filename),
+ path = server + "/",
+ suffix = server === "net" ? ".ashx" : "." + server;
- } else {
- grunt.log.warn('config file update error');
- }
+ file = file.replace(/php\//ig, path).replace(/\.php/ig, suffix);
+ if (encode == "gbk") {
+ file = file.replace(/utf-8/gi, "gbk");
}
-};
\ No newline at end of file
+ //写入到dist
+ if (grunt.file.write(disDir + filename, file)) {
+ grunt.log.writeln("config file update success");
+ } else {
+ grunt.log.warn("config file update error");
+ }
+ }
+};
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..d6036bc4b
--- /dev/null
+++ b/ISSUE_TEMPLATE.md
@@ -0,0 +1,24 @@
+**声明:如果不看该说明,只在标题中描述问题,一律忽略**
+
+**首先**,感谢各位使用 UEditor,并来到这儿提 `ISSUE`。
+
+**其次**,在回答大量用户提出的 `ISSUE` 的过程中,我们发现需要建立一个提 `ISSUE` 的规则,
+将我们的主要精力投入到修复 `UEditor` Bugs 和改进 `UEditor` 中去,让越来越多的人能够使用的舒心。
+
+## 规则
+
+* 提 `ISSUE` 之前,**请先看看文档**。传送门:[文档](http://fex.baidu.com/ueditor/)。很多问题,在文档中都能有答案。特别是配置之类的。
+* 提 `ISSUE` 之前,**请先问问搜索引擎(百度、Google)**,因为你遇到的问题,可能其他人也遇到了,并且已经解决了。
+只需要动动手指,在输入框里输入,就会有答案,这样方便,远比等我们回复快捷。
+* 提 `ISSUE` 之前,如果你已经走过上面两步了,来到 `ISSUE` 这个页面了,此刻,请别急,**建议你再搜索一下`ISSUE`**。
+因为,或许你将提的问题,也有人遇到了,而且我们已经反馈了。这时,你只需要找到相应的 `ISSUE`,在那个 `ISSUE` 里留下你的关注就好了。很简单吧!
+
+以上都不满足你,看来这一定是个新的问题。首先,我们要感谢你,帮我们发现了一个新的问题,但是,为了使问题能尽快得到解决。我们建议你按照如下的规则来提:
+
+* 构想清楚问题的表达;
+* 写一个简明扼要的标题
+* 写一个能描述清楚问题的内容,如果有复现步骤及截图当是极好的;
+
+**最后,是我们的一点希望:希望提 `ISSUE` 的同学,能自行排查、定位问题,甚至自行修复,然后给我们提 `Pull Request`。即使做不到提 `Pull Request`,但是你的排查的过程也是在增加你的 `debug` 的能力。**
+
+### 再次感谢各位选择 `UEditor`!
diff --git a/README.md b/README.md
index ac23f0da2..1e2e730e6 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,26 @@
-UEditor
-======
+Get Started
+=====
-**UEditor富文本编辑器**
+> 鉴于目前 ISSUE 较多而维护时间较少,且在进行后续的版本更新,目前暂时关闭 ISSUE,若社区有人跟进,欢迎和我们联系。重复的问题,请参阅常见问题的 [FAQ Wiki](https://github.com/fex-team/ueditor/wiki/FAQ)。
+
+## 重要安全通告:
+
+1. commons-fileupload-1.3.1.jar 存在漏洞可能会导致 ddos,源代码中已经修改,使用老版本的用户,强烈推荐升级 commons-fileupload.jar 至最新版本。(2018-04-09).
+2. UEditor 所提供的所有后端代码都仅为 DEMO 作用,切不可直接使用到生产环境中,目前已知 php 的代码会存在 ssrf 及文件包含漏洞,因此不再提供。
+
+## ueditor富文本编辑器介绍
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。
-## 入门部署和体验 ##
+## 1 入门部署和体验
-### 第一步:下载编辑器 ###
+### 1.1 下载编辑器
-到官网下载ueditor最新版: [[官网地址]](http://ueditor.baidu.com/website/download.html#ueditor "官网地址") [[1.3.5下载地址]](http://ueditor.baidu.com/build/build_down.php?t=1_3_5-src)
+1. `git clone ` 仓库
+2. `npm install` 安装依赖(如果没有安装 grunt , 请先在全局安装 grunt)
+3. 在终端执行 `grunt default`
-### 第二步:创建demo文件 ###
+### 1.2 创建demo文件
解压下载的包,在解压后的目录创建demo.html文件,填入下面的html代码
```html
@@ -30,48 +39,71 @@ UEditor是由百度web前端研发部开发所见即所得富文本web编辑器