From 93f3664c8846d3cb5268ca678e47713c1826bfcf Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Oct 2016 23:04:26 +0800 Subject: [PATCH 01/54] Add missing vendor code hard to deal with --- public/vendor/idle.min.js | 2 + public/vendor/jquery-scrollspy.js | 267 ++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 public/vendor/idle.min.js create mode 100644 public/vendor/jquery-scrollspy.js diff --git a/public/vendor/idle.min.js b/public/vendor/idle.min.js new file mode 100644 index 0000000..d6fe0d3 --- /dev/null +++ b/public/vendor/idle.min.js @@ -0,0 +1,2 @@ +/*! Idle.Js, copyright 2015-01-01, Shawn Mclean*/ +(function(){var a;document.addEventListener||(document.addEventListener=document.attachEvent?function(a,b,c){return document.attachEvent("on"+a,b,c)}:function(){return{}}),document.removeEventListener||(document.removeEventListener=document.detachEvent?function(a,b){return document.detachEvent("on"+a,b)}:function(){return{}}),a={},a=function(){function a(a){var b,c;a&&(this.awayTimeout=parseInt(a.awayTimeout,10),this.onAway=a.onAway,this.onAwayBack=a.onAwayBack,this.onVisible=a.onVisible,this.onHidden=a.onHidden),c=this,b=function(){return c.onActive()},window.onclick=b,window.onmousemove=b,window.onmouseenter=b,window.onkeydown=b,window.onscroll=b,window.onmousewheel=b}return a.isAway=!1,a.awayTimeout=3e3,a.awayTimestamp=0,a.awayTimer=null,a.onAway=null,a.onAwayBack=null,a.onVisible=null,a.onHidden=null,a.prototype.onActive=function(){return this.awayTimestamp=(new Date).getTime()+this.awayTimeout,this.isAway&&(this.onAwayBack&&this.onAwayBack(),this.start()),this.isAway=!1,!0},a.prototype.start=function(){var a;return this.listener||(this.listener=function(){return a.handleVisibilityChange()},document.addEventListener("visibilitychange",this.listener,!1),document.addEventListener("webkitvisibilitychange",this.listener,!1),document.addEventListener("msvisibilitychange",this.listener,!1)),this.awayTimestamp=(new Date).getTime()+this.awayTimeout,null!==this.awayTimer&&clearTimeout(this.awayTimer),a=this,this.awayTimer=setTimeout(function(){return a.checkAway()},this.awayTimeout+100),this},a.prototype.stop=function(){return null!==this.awayTimer&&clearTimeout(this.awayTimer),null!==this.listener&&(document.removeEventListener("visibilitychange",this.listener),document.removeEventListener("webkitvisibilitychange",this.listener),document.removeEventListener("msvisibilitychange",this.listener),this.listener=null),this},a.prototype.setAwayTimeout=function(a){return this.awayTimeout=parseInt(a,10),this},a.prototype.checkAway=function(){var a,b;return b=(new Date).getTime(),b= min && xAndY <= max) { + // trigger the 'scrollEnter' event + if (!inside) { + inside = true; + enters++; + + // trigger the 'scrollEnter' event + $element.trigger('scrollEnter', { + position: position, + }); + + // call the 'onEnter' function + if (options.onEnter !== null) { + options.onEnter(_this, position); + } + } + + // trigger the 'scrollTick' event + $element.trigger('scrollTick', { + position: position, + inside: inside, + enters: enters, + leaves: leaves, + }); + + // call the 'onTick' function + if (options.onTick !== null) { + options.onTick(_this, position, inside, enters, leaves); + } + } else { + if (inside) { + inside = false; + leaves++; + + // trigger the 'scrollLeave' event + $element.trigger('scrollLeave', { + position: position, + leaves: leaves, + }); + + // call the 'onLeave' function + if (options.onLeave !== null) { + options.onLeave(_this, position); + } + + if (xAndY <= min) { + // trigger the 'scrollLeaveTop' event + $element.trigger('scrollLeaveTop', { + position: position, + leaves: leaves, + }); + + // call the 'onLeaveTop' function + if (options.onLeaveTop !== null) { + options.onLeaveTop(_this, position); + } + } else if (xAndY >= max) { + // trigger the 'scrollLeaveBottom' event + $element.trigger('scrollLeaveBottom', { + position: position, + leaves: leaves, + }); + + // call the 'onLeaveBottom' function + if (options.onLeaveBottom !== null) { + options.onLeaveBottom(_this, position); + } + } + } else { + // Idea taken from: http://stackoverflow.com/questions/5353934/check-if-element-is-visible-on-screen + var containerScrollTop = $container.scrollTop(); + + // Get the element height + var elementHeight = $element.height(); + + // Get the element offset + var elementOffsetTop = $element.offset().top; + + if ((elementOffsetTop < (containerHeight + containerScrollTop)) && (elementOffsetTop > (containerScrollTop - elementHeight))) { + // trigger the 'scrollView' event + $element.trigger('scrollView', { + position: position, + }); + + // call the 'onView' function + if (options.onView !== null) { + options.onView(_this, position); + } + } + } + } + }); + }); + }, + }); + + // Fields (Private) + + // Defaults + + // default options + var _defaults = { + // the offset to be applied to the left and top positions of the container + buffer: 0, + + // the element to apply the 'scrolling' event to (default window) + container: window, + + // the maximum value of the X or Y coordinate, depending on mode the selected + max: 0, + + // the maximum value of the X or Y coordinate, depending on mode the selected + min: 0, + + // whether to listen to the X (horizontal) or Y (vertical) scrolling + mode: 'vertical', + + // namespace to append to the 'scroll' event + namespace: 'scrollspy', + + // call the following callback function every time the user enters the min / max zone + onEnter: null, + + // call the following callback function every time the user leaves the min / max zone + onLeave: null, + + // call the following callback function every time the user leaves the top zone + onLeaveTop: null, + + // call the following callback function every time the user leaves the bottom zone + onLeaveBottom: null, + + // call the following callback function on each scroll event within the min and max parameters + onTick: null, + + // call the following callback function on each scroll event when the element is inside the viewable view port + onView: null, + }; + + // Methods (Private) + + // check if a value is an object datatype + function _isObject(value) { + return $.type(value) === 'object'; + } + + // check if a value is a string datatype with a length greater than zero when whitespace is stripped + function _isString(value) { + return $.type(value) === 'string' && $.trim(value).length > 0; + } + + // check if an option is correctly formatted using a predicate; otherwise, return the default value + function _sanitizeOption(options, defaults, property, predicate) { + // set the property to the default value if the predicate returned false + if (!predicate(options[property])) { + options[property] = defaults[property]; + } + } +}(window, window.jQuery)); From f0269a161c06dc3a9990a4c82b30e500d690d30b Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Oct 2016 23:04:39 +0800 Subject: [PATCH 02/54] Exclude webpack build folder --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f6c8d5d..8a2ca18 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ backups/ config.json public/js/common.js .sequelizerc + +# ignore webpack build +public/build From 325d1f1a326a4ef5eaa070e56665c9b5680f1e36 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Oct 2016 23:05:23 +0800 Subject: [PATCH 03/54] Create webpack config --- package.json | 67 +++++++++++++++++++++++++++++++++++++++++++---- webpack.config.js | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 webpack.config.js diff --git a/package.json b/package.json index 94b08ea..6ca6719 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,18 @@ "description": "Realtime collaborative markdown notes on all platforms.", "main": "app.js", "license": "MIT", + "scripts": { + "build": "webpack --config webpack.config.js --progress --colors --watch" + }, "dependencies": { + "Idle.Js": "github:shawnmclean/Idle.js", "async": "^2.0.1", "blueimp-md5": "^2.3.0", "body-parser": "^1.15.2", + "bootstrap": "^3.3.7", "chance": "^1.0.4", "cheerio": "^0.20.0", + "codemirror": "^5.19.0", "compression": "^1.6.2", "connect-session-sequelize": "^3.1.0", "cookie": "0.3.1", @@ -19,14 +25,39 @@ "emojify.js": "^1.1.0", "express": ">=4.14", "express-session": "^1.14.0", + "file-saver": "^1.3.3", + "flowchart.js": "^1.6.3", "formidable": "^1.0.17", + "gist-embed": "github:yukaii/gist-embed", + "handlebars": "^4.0.5", "helmet": "^2.1.2", - "highlight.js": "^9.5.0", + "highlight.js": "^9.7.0", "i18n": "^0.8.3", "imgur": "git+https://github.com/hackmdio/node-imgur.git", + "jquery": "^3.1.1", + "jquery-mousewheel": "^3.1.13", + "jquery-textcomplete": "^1.7.3", + "jquery-ui": "^1.12.1", + "js-cookie": "^2.1.3", + "js-sequence-diagrams": "^1000000.0.6", + "js-url": "^2.3.0", "jsdom-nogyp": "^0.8.3", + "keymaster": "^1.6.2", + "list.js": "^1.2.0", + "lodash": "^4.16.4", "lz-string": "1.4.4", - "markdown-it": "^7.0.0", + "markdown-it": "^7.0.1", + "markdown-it-abbr": "^1.0.4", + "markdown-it-container": "^2.0.0", + "markdown-it-deflist": "^2.0.1", + "markdown-it-footnote": "^3.0.1", + "markdown-it-imsize": "^2.0.1", + "markdown-it-ins": "^2.0.0", + "markdown-it-mark": "^2.0.0", + "markdown-it-mathjax": "^1.0.3", + "markdown-it-regexp": "^0.4.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", "markdown-pdf": "^7.0.0", "meta-marked": "^0.4.1", "method-override": "^2.3.6", @@ -42,9 +73,12 @@ "passport-google-oauth20": "^1.0.0", "passport-twitter": "^1.0.4", "passport.socketio": "^3.6.2", + "pdfobject": "^2.0.201604172", "pg": "^6.0.3", "pg-hstore": "^2.3.2", + "prismjs": "^1.5.1", "randomcolor": "^0.4.4", + "raphael": "github:dmitrybaranovskiy/raphael", "request": "^2.74.0", "reveal.js": "3.3.0", "sequelize": "^3.23.6", @@ -52,20 +86,43 @@ "shortid": "2.2.6", "socket.io": "1.4.8", "sqlite3": "^3.1.4", + "store": "^1.3.20", "string": "^3.3.1", "tedious": "^1.14.0", + "to-markdown": "^3.0.1", "toobusy-js": "^0.5.1", - "winston": "^2.2.0" + "visibilityjs": "^1.2.4", + "viz.js": "^1.3.0", + "winston": "^2.2.0", + "xss": "^0.2.13" }, "engines": { "node": ">=4.x" }, "bugs": "https://github.com/hackmdio/hackmd/issues", - "keywords": ["Collaborative", "Markdown", "Notes"], + "keywords": [ + "Collaborative", + "Markdown", + "Notes" + ], "homepage": "https://hackmd.io", - "maintainers": [{"name": "Max Wu", "email": "jackymaxj@gmail.com"}], + "maintainers": [ + { + "name": "Max Wu", + "email": "jackymaxj@gmail.com" + } + ], "repository": { "type": "git", "url": "https://github.com/hackmdio/hackmd.git" + }, + "devDependencies": { + "babel-loader": "^6.2.5", + "bower-webpack-plugin": "^0.1.9", + "css-loader": "^0.25.0", + "extract-text-webpack-plugin": "^1.0.1", + "imports-loader": "^0.6.5", + "json-loader": "^0.5.4", + "webpack": "^1.13.2" } } diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..01adea9 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,64 @@ +var webpack = require('webpack'); +var path = require('path'); +var ExtractTextPlugin = require("extract-text-webpack-plugin"); + +module.exports = { + plugins: [ + new webpack.ProvidePlugin({ + '_': 'lodash', + jquery: "jquery", + jQuery: "jquery", + $: "jquery", + "window.jQuery": "jquery", + Visibility: "visibilityjs", + Cookies: "js-cookie", + CodeMirror: "codemirror" + }), + new webpack.DefinePlugin({ + "require.specified": "require.resolve" + }) + ], + + entry: { + app: path.join(__dirname, 'public/js/app.js') + }, + + output: { + path: path.join(__dirname, 'public/build/js'), + filename: '[name].js' + }, + + resolve: { + root: [ + path.resolve(__dirname, 'src'), + path.resolve(__dirname, 'node_modules') + ], + extensions: ["", ".js"], + alias: { + 'jquery-ui': 'jquery-ui/ui/widgets' + } + }, + + module: { + loaders: [{ + test: /\.json$/, + loader: 'json-loader' + }, { + test: /\.css$/, + loader: ExtractTextPlugin.extract({ + fallbackLoader: "style-loader", + loader: "css-loader" + }) + }, { + test: /\.scss$/, + loaders: ['style', 'css', 'sass'] + }, { + test: require.resolve("js-sequence-diagrams"), + loader: "imports?Raphael=raphael" + }] + }, + + node: { + fs: "empty" + } +}; From 8e11c19bed6b99b5476d9d7a6125dcfdd4119064 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Oct 2016 23:06:10 +0800 Subject: [PATCH 04/54] Move out script tag and use js instead --- public/js/app.js | 1 + public/js/index.js | 82 ++++++++++++++++++++++++++++++++++++++++--- public/views/foot.ejs | 55 ++--------------------------- 3 files changed, 80 insertions(+), 58 deletions(-) create mode 100644 public/js/app.js diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..fe86450 --- /dev/null +++ b/public/js/app.js @@ -0,0 +1 @@ +require('./index'); diff --git a/public/js/index.js b/public/js/index.js index 03729de..9590a4e 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -1,3 +1,75 @@ +/* include jquery ui */ +require('jquery-ui/ui/widgets/resizable'); +require('jquery-ui/ui/widgets/tooltip'); +require('jquery-ui/ui/widgets/controlgroup'); +require('jquery-ui/ui/widgets/autocomplete'); + +/* jquery and jquery plugins */ +require('jquery'); +require('jquery-textcomplete'); +require('jquery-mousewheel'); +require('../vendor/jquery-scrollspy'); +require('../vendor/showup/showup'); + +/* bootstrap */ +require('bootstrap'); + +/* code mirror plugins */ +require('codemirror/keymap/vim'); +require('codemirror/keymap/emacs'); +require('codemirror/keymap/sublime'); + +require('../vendor/inlineAttachment/inline-attachment'); +require('../vendor/inlineAttachment/codemirror.inline-attachment'); +require('../vendor/codemirror-spell-checker/spell-checker.min'); + +/* operational transformation */ +require('../vendor/ot/ot.min'); + +/* other vendors plugin */ +require('markdown-it'); +require('markdown-it-abbr'); +require('markdown-it-footnote'); +require('markdown-it-deflist'); +require('markdown-it-mark'); +require('markdown-it-ins'); +require('markdown-it-sub'); +require('markdown-it-sup'); +require('markdown-it-container'); +require('markdown-it-mathjax'); +require('markdown-it-regexp'); +require('markdown-it-imsize'); + +require('gist-embed'); +require('lz-string'); +require('xss'); +require('string'); +require('highlight.js'); +require('prismjs'); +require('prismjs/components/prism-wiki'); +require('js-cookie'); +require('emojify.js'); +require('to-markdown'); + +require('raphael'); +require('js-sequence-diagrams'); + +require('flowchart.js'); +require('viz.js'); +require('pdfobject'); +require('file-saver'); +require('store'); +require('js-url'); +require('visibilityjs'); +require('list.js'); +require('../vendor/md-toc'); +require('randomcolor'); +require('keymaster'); + +var common = require('./common.js'); + +var serverurl = common.serverurl; + var defaultTextHeight = 20; var viewportMargin = 20; var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault; @@ -126,7 +198,7 @@ function wrapTextWith(cm, symbol) { }; var postText = cm.getRange(postEndPos, from); var postIndex = wrapSymbols.indexOf(postText); - // check if surround symbol are list in array and matched + // check if surround symbol are list in array and matched if (preIndex > -1 && postIndex > -1 && preIndex === postIndex) { cm.replaceRange("", to, preEndPos, '+delete'); cm.replaceRange("", postEndPos, from, '+delete'); @@ -1035,7 +1107,7 @@ function checkEditorStyle() { }, stop: function (e) { lastEditorWidth = ui.area.edit.width(); - // workaround that scroll event bindings + // workaround that scroll event bindings preventSyncScrollToView = 2; preventSyncScrollToEdit = true; editor.setOption('viewportMargin', viewportMargin); @@ -1269,12 +1341,12 @@ function changeMode(type) { preventSyncScrollToView = 2; syncScrollToEdit(null, true); } - + if (lastMode == modeType.edit && currentMode == modeType.both) { preventSyncScrollToEdit = 2; syncScrollToView(null, true); } - + if (lastMode == modeType.both && currentMode != modeType.both) { preventSyncScrollToView = false; preventSyncScrollToEdit = false; @@ -1675,7 +1747,7 @@ function parseRevisions(_revisions) { } } function selectRevision(time) { - if (time == revisionTime) return; + if (time == revisionTime) return; $.get(noteurl + '/revision/' + time) .done(function(data) { revision = data; diff --git a/public/views/foot.ejs b/public/views/foot.ejs index 9328ac9..128302f 100644 --- a/public/views/foot.ejs +++ b/public/views/foot.ejs @@ -14,65 +14,15 @@ <% } else { %> - - - <% } %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -81,4 +31,3 @@ - \ No newline at end of file From b8467a562c087a63c30d2cfe02494ab3229fa89b Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sat, 8 Oct 2016 10:07:12 +0800 Subject: [PATCH 05/54] Remove Idle.Js dependency use vendor minified js for now --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 6ca6719..308d828 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "build": "webpack --config webpack.config.js --progress --colors --watch" }, "dependencies": { - "Idle.Js": "github:shawnmclean/Idle.js", "async": "^2.0.1", "blueimp-md5": "^2.3.0", "body-parser": "^1.15.2", From ab2131116181a95e9eefa410bac25682396b2e05 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sat, 8 Oct 2016 10:16:49 +0800 Subject: [PATCH 06/54] Change npm task 'build' to 'dev' --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 308d828..4ff2d25 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "app.js", "license": "MIT", "scripts": { - "build": "webpack --config webpack.config.js --progress --colors --watch" + "dev": "webpack --config webpack.config.js --progress --colors --watch" }, "dependencies": { "async": "^2.0.1", From ebee5a8d05a0282f5f584abc7d1eaa26d9d17ad8 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sat, 8 Oct 2016 19:56:38 +0800 Subject: [PATCH 07/54] Use xss in script tag --- package.json | 3 +-- public/js/index.js | 1 - public/vendor/xss.min.js | 1 + public/views/foot.ejs | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 public/vendor/xss.min.js diff --git a/package.json b/package.json index 4ff2d25..5c71cd0 100644 --- a/package.json +++ b/package.json @@ -92,8 +92,7 @@ "toobusy-js": "^0.5.1", "visibilityjs": "^1.2.4", "viz.js": "^1.3.0", - "winston": "^2.2.0", - "xss": "^0.2.13" + "winston": "^2.2.0" }, "engines": { "node": ">=4.x" diff --git a/public/js/index.js b/public/js/index.js index 9590a4e..90a3daf 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -42,7 +42,6 @@ require('markdown-it-imsize'); require('gist-embed'); require('lz-string'); -require('xss'); require('string'); require('highlight.js'); require('prismjs'); diff --git a/public/vendor/xss.min.js b/public/vendor/xss.min.js new file mode 100644 index 0000000..48d7880 --- /dev/null +++ b/public/vendor/xss.min.js @@ -0,0 +1 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o/g;var REGEXP_QUOTE=/"/g;var REGEXP_QUOTE_2=/"/g;var REGEXP_ATTR_VALUE_1=/&#([a-zA-Z0-9]*);?/gim;var REGEXP_ATTR_VALUE_COLON=/:?/gim;var REGEXP_ATTR_VALUE_NEWLINE=/&newline;?/gim;var REGEXP_DEFAULT_ON_TAG_ATTR_3=/\/\*|\*\//gm;var REGEXP_DEFAULT_ON_TAG_ATTR_4=/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_5=/^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_6=/^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi;var REGEXP_DEFAULT_ON_TAG_ATTR_7=/e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_8=/u\s*r\s*l\s*\(.*/gi;function escapeQuote(str){return str.replace(REGEXP_QUOTE,""")}function unescapeQuote(str){return str.replace(REGEXP_QUOTE_2,'"')}function escapeHtmlEntities(str){return str.replace(REGEXP_ATTR_VALUE_1,function replaceUnicode(str,code){return code[0]==="x"||code[0]==="X"?String.fromCharCode(parseInt(code.substr(1),16)):String.fromCharCode(parseInt(code,10))})}function escapeDangerHtml5Entities(str){return str.replace(REGEXP_ATTR_VALUE_COLON,":").replace(REGEXP_ATTR_VALUE_NEWLINE," ")}function clearNonPrintableCharacter(str){var str2="";for(var i=0,len=str.length;i/g;function stripBlankChar(html){var chars=html.split("");chars=chars.filter(function(char){var c=char.charCodeAt(0);if(c===127)return false;if(c<=31){if(c===10||c===13)return true;return false}return true});return chars.join("")}exports.whiteList=getDefaultWhiteList();exports.getDefaultWhiteList=getDefaultWhiteList;exports.onTag=onTag;exports.onIgnoreTag=onIgnoreTag;exports.onTagAttr=onTagAttr;exports.onIgnoreTagAttr=onIgnoreTagAttr;exports.safeAttrValue=safeAttrValue;exports.escapeHtml=escapeHtml;exports.escapeQuote=escapeQuote;exports.unescapeQuote=unescapeQuote;exports.escapeHtmlEntities=escapeHtmlEntities;exports.escapeDangerHtml5Entities=escapeDangerHtml5Entities;exports.clearNonPrintableCharacter=clearNonPrintableCharacter;exports.friendlyAttrValue=friendlyAttrValue;exports.escapeAttrValue=escapeAttrValue;exports.onIgnoreTagStripAll=onIgnoreTagStripAll;exports.StripTagBody=StripTagBody;exports.stripCommentTag=stripCommentTag;exports.stripBlankChar=stripBlankChar;exports.cssFilter=defaultCSSFilter},{"./util":4,cssfilter:8}],2:[function(require,module,exports){var DEFAULT=require("./default");var parser=require("./parser");var FilterXSS=require("./xss");function filterXSS(html,options){var xss=new FilterXSS(options);return xss.process(html)}exports=module.exports=filterXSS;exports.FilterXSS=FilterXSS;for(var i in DEFAULT)exports[i]=DEFAULT[i];for(var i in parser)exports[i]=parser[i];if(typeof window!=="undefined"){window.filterXSS=module.exports}},{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){var _=require("./util");function getTagName(html){var i=html.indexOf(" ");if(i===-1){var tagName=html.slice(1,-1)}else{var tagName=html.slice(1,i+1)}tagName=_.trim(tagName).toLowerCase();if(tagName.slice(0,1)==="/")tagName=tagName.slice(1);if(tagName.slice(-1)==="/")tagName=tagName.slice(0,-1);return tagName}function isClosing(html){return html.slice(0,2)===""){rethtml+=escapeHtml(html.slice(lastPos,tagStart));currentHtml=html.slice(tagStart,currentPos+1);currentTagName=getTagName(currentHtml);rethtml+=onTag(tagStart,rethtml.length,currentTagName,currentHtml,isClosing(currentHtml));lastPos=currentPos+1;tagStart=false;continue}if((c==='"'||c==="'")&&html.charAt(currentPos-1)==="="){quoteStart=c;continue}}else{if(c===quoteStart){quoteStart=false;continue}}}}if(lastPos0;i--){var c=str[i];if(c===" ")continue;if(c==="=")return i;return-1}}function isQuoteWrapString(text){if(text[0]==='"'&&text[text.length-1]==='"'||text[0]==="'"&&text[text.length-1]==="'"){return true}else{return false}}function stripQuoteWrap(text){if(isQuoteWrapString(text)){return text.substr(1,text.length-2)}else{return text}}exports.parseTag=parseTag;exports.parseAttr=parseAttr},{"./util":4}],4:[function(require,module,exports){module.exports={indexOf:function(arr,item){var i,j;if(Array.prototype.indexOf){return arr.indexOf(item)}for(i=0,j=arr.length;i"}var attrs=getAttrs(html);var whiteAttrList=whiteList[tag];var attrsHtml=parseAttr(attrs.html,function(name,value){var isWhiteAttr=_.indexOf(whiteAttrList,name)!==-1;var ret=onTagAttr(tag,name,value,isWhiteAttr);if(!isNull(ret))return ret;if(isWhiteAttr){value=safeAttrValue(tag,name,value,cssFilter);if(value){return name+'="'+value+'"'}else{return name}}else{var ret=onIgnoreTagAttr(tag,name,value,isWhiteAttr);if(!isNull(ret))return ret;return}});var html="<"+tag;if(attrsHtml)html+=" "+attrsHtml;if(attrs.closing)html+=" /";html+=">";return html}else{var ret=onIgnoreTag(tag,html,info);if(!isNull(ret))return ret;return escapeHtml(html)}},escapeHtml);if(stripIgnoreTagBody){retHtml=stripIgnoreTagBody.remove(retHtml)}return retHtml};module.exports=FilterXSS},{"./default":1,"./parser":3,"./util":4,cssfilter:8}],6:[function(require,module,exports){var DEFAULT=require("./default");var parseStyle=require("./parser");var _=require("./util");function isNull(obj){return obj===undefined||obj===null}function FilterCSS(options){options=options||{};options.whiteList=options.whiteList||DEFAULT.whiteList;options.onAttr=options.onAttr||DEFAULT.onAttr;options.onIgnoreAttr=options.onIgnoreAttr||DEFAULT.onIgnoreAttr;this.options=options}FilterCSS.prototype.process=function(css){css=css||"";css=css.toString();if(!css)return"";var me=this;var options=me.options;var whiteList=options.whiteList;var onAttr=options.onAttr;var onIgnoreAttr=options.onIgnoreAttr;var retCSS=parseStyle(css,function(sourcePosition,position,name,value,source){var check=whiteList[name];var isWhite=false;if(check===true)isWhite=check;else if(typeof check==="function")isWhite=check(value);else if(check instanceof RegExp)isWhite=check.test(value);if(isWhite!==true)isWhite=false;var opts={position:position,sourcePosition:sourcePosition,source:source,isWhite:isWhite};if(isWhite){var ret=onAttr(name,value,opts);if(isNull(ret)){return name+":"+value}else{return ret}}else{var ret=onIgnoreAttr(name,value,opts);if(!isNull(ret)){return ret}}});return retCSS};module.exports=FilterCSS},{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){function getDefaultWhiteList(){var whiteList={};whiteList["align-content"]=false;whiteList["align-items"]=false;whiteList["align-self"]=false;whiteList["alignment-adjust"]=false;whiteList["alignment-baseline"]=false;whiteList["all"]=false;whiteList["anchor-point"]=false;whiteList["animation"]=false;whiteList["animation-delay"]=false;whiteList["animation-direction"]=false;whiteList["animation-duration"]=false;whiteList["animation-fill-mode"]=false;whiteList["animation-iteration-count"]=false;whiteList["animation-name"]=false;whiteList["animation-play-state"]=false;whiteList["animation-timing-function"]=false;whiteList["azimuth"]=false;whiteList["backface-visibility"]=false;whiteList["background"]=true;whiteList["background-attachment"]=true;whiteList["background-clip"]=true;whiteList["background-color"]=true;whiteList["background-image"]=true;whiteList["background-origin"]=true;whiteList["background-position"]=true;whiteList["background-repeat"]=true;whiteList["background-size"]=true;whiteList["baseline-shift"]=false;whiteList["binding"]=false;whiteList["bleed"]=false;whiteList["bookmark-label"]=false;whiteList["bookmark-level"]=false;whiteList["bookmark-state"]=false;whiteList["border"]=true;whiteList["border-bottom"]=true;whiteList["border-bottom-color"]=true;whiteList["border-bottom-left-radius"]=true;whiteList["border-bottom-right-radius"]=true;whiteList["border-bottom-style"]=true;whiteList["border-bottom-width"]=true;whiteList["border-collapse"]=true;whiteList["border-color"]=true;whiteList["border-image"]=true;whiteList["border-image-outset"]=true;whiteList["border-image-repeat"]=true;whiteList["border-image-slice"]=true;whiteList["border-image-source"]=true;whiteList["border-image-width"]=true;whiteList["border-left"]=true;whiteList["border-left-color"]=true;whiteList["border-left-style"]=true;whiteList["border-left-width"]=true;whiteList["border-radius"]=true;whiteList["border-right"]=true;whiteList["border-right-color"]=true;whiteList["border-right-style"]=true;whiteList["border-right-width"]=true;whiteList["border-spacing"]=true;whiteList["border-style"]=true;whiteList["border-top"]=true;whiteList["border-top-color"]=true;whiteList["border-top-left-radius"]=true;whiteList["border-top-right-radius"]=true;whiteList["border-top-style"]=true;whiteList["border-top-width"]=true;whiteList["border-width"]=true;whiteList["bottom"]=false;whiteList["box-decoration-break"]=true;whiteList["box-shadow"]=true;whiteList["box-sizing"]=true;whiteList["box-snap"]=true;whiteList["box-suppress"]=true;whiteList["break-after"]=true;whiteList["break-before"]=true;whiteList["break-inside"]=true;whiteList["caption-side"]=false;whiteList["chains"]=false;whiteList["clear"]=true;whiteList["clip"]=false;whiteList["clip-path"]=false;whiteList["clip-rule"]=false;whiteList["color"]=true;whiteList["color-interpolation-filters"]=true;whiteList["column-count"]=false;whiteList["column-fill"]=false;whiteList["column-gap"]=false;whiteList["column-rule"]=false;whiteList["column-rule-color"]=false;whiteList["column-rule-style"]=false;whiteList["column-rule-width"]=false;whiteList["column-span"]=false;whiteList["column-width"]=false;whiteList["columns"]=false;whiteList["contain"]=false;whiteList["content"]=false;whiteList["counter-increment"]=false;whiteList["counter-reset"]=false;whiteList["counter-set"]=false;whiteList["crop"]=false;whiteList["cue"]=false;whiteList["cue-after"]=false;whiteList["cue-before"]=false;whiteList["cursor"]=false;whiteList["direction"]=false;whiteList["display"]=true;whiteList["display-inside"]=true;whiteList["display-list"]=true;whiteList["display-outside"]=true;whiteList["dominant-baseline"]=false;whiteList["elevation"]=false;whiteList["empty-cells"]=false;whiteList["filter"]=false;whiteList["flex"]=false;whiteList["flex-basis"]=false;whiteList["flex-direction"]=false;whiteList["flex-flow"]=false;whiteList["flex-grow"]=false;whiteList["flex-shrink"]=false;whiteList["flex-wrap"]=false;whiteList["float"]=false;whiteList["float-offset"]=false;whiteList["flood-color"]=false;whiteList["flood-opacity"]=false;whiteList["flow-from"]=false;whiteList["flow-into"]=false;whiteList["font"]=true;whiteList["font-family"]=true;whiteList["font-feature-settings"]=true;whiteList["font-kerning"]=true;whiteList["font-language-override"]=true;whiteList["font-size"]=true;whiteList["font-size-adjust"]=true;whiteList["font-stretch"]=true;whiteList["font-style"]=true;whiteList["font-synthesis"]=true;whiteList["font-variant"]=true;whiteList["font-variant-alternates"]=true;whiteList["font-variant-caps"]=true;whiteList["font-variant-east-asian"]=true;whiteList["font-variant-ligatures"]=true;whiteList["font-variant-numeric"]=true;whiteList["font-variant-position"]=true;whiteList["font-weight"]=true;whiteList["grid"]=false;whiteList["grid-area"]=false;whiteList["grid-auto-columns"]=false;whiteList["grid-auto-flow"]=false;whiteList["grid-auto-rows"]=false;whiteList["grid-column"]=false;whiteList["grid-column-end"]=false;whiteList["grid-column-start"]=false;whiteList["grid-row"]=false;whiteList["grid-row-end"]=false;whiteList["grid-row-start"]=false;whiteList["grid-template"]=false;whiteList["grid-template-areas"]=false;whiteList["grid-template-columns"]=false;whiteList["grid-template-rows"]=false;whiteList["hanging-punctuation"]=false;whiteList["height"]=true;whiteList["hyphens"]=false;whiteList["icon"]=false;whiteList["image-orientation"]=false;whiteList["image-resolution"]=false;whiteList["ime-mode"]=false;whiteList["initial-letters"]=false;whiteList["inline-box-align"]=false;whiteList["justify-content"]=false;whiteList["justify-items"]=false;whiteList["justify-self"]=false;whiteList["left"]=false;whiteList["letter-spacing"]=true;whiteList["lighting-color"]=true;whiteList["line-box-contain"]=false;whiteList["line-break"]=false;whiteList["line-grid"]=false;whiteList["line-height"]=false;whiteList["line-snap"]=false;whiteList["line-stacking"]=false;whiteList["line-stacking-ruby"]=false;whiteList["line-stacking-shift"]=false;whiteList["line-stacking-strategy"]=false;whiteList["list-style"]=true;whiteList["list-style-image"]=true;whiteList["list-style-position"]=true;whiteList["list-style-type"]=true;whiteList["margin"]=true;whiteList["margin-bottom"]=true;whiteList["margin-left"]=true;whiteList["margin-right"]=true;whiteList["margin-top"]=true;whiteList["marker-offset"]=false;whiteList["marker-side"]=false;whiteList["marks"]=false;whiteList["mask"]=false;whiteList["mask-box"]=false;whiteList["mask-box-outset"]=false;whiteList["mask-box-repeat"]=false;whiteList["mask-box-slice"]=false;whiteList["mask-box-source"]=false;whiteList["mask-box-width"]=false;whiteList["mask-clip"]=false;whiteList["mask-image"]=false;whiteList["mask-origin"]=false;whiteList["mask-position"]=false;whiteList["mask-repeat"]=false;whiteList["mask-size"]=false;whiteList["mask-source-type"]=false;whiteList["mask-type"]=false;whiteList["max-height"]=true;whiteList["max-lines"]=false;whiteList["max-width"]=true;whiteList["min-height"]=true;whiteList["min-width"]=true;whiteList["move-to"]=false;whiteList["nav-down"]=false;whiteList["nav-index"]=false;whiteList["nav-left"]=false;whiteList["nav-right"]=false;whiteList["nav-up"]=false;whiteList["object-fit"]=false;whiteList["object-position"]=false;whiteList["opacity"]=false;whiteList["order"]=false;whiteList["orphans"]=false;whiteList["outline"]=false;whiteList["outline-color"]=false;whiteList["outline-offset"]=false;whiteList["outline-style"]=false;whiteList["outline-width"]=false;whiteList["overflow"]=false;whiteList["overflow-wrap"]=false;whiteList["overflow-x"]=false;whiteList["overflow-y"]=false;whiteList["padding"]=true;whiteList["padding-bottom"]=true;whiteList["padding-left"]=true;whiteList["padding-right"]=true;whiteList["padding-top"]=true;whiteList["page"]=false;whiteList["page-break-after"]=false;whiteList["page-break-before"]=false;whiteList["page-break-inside"]=false;whiteList["page-policy"]=false;whiteList["pause"]=false;whiteList["pause-after"]=false;whiteList["pause-before"]=false;whiteList["perspective"]=false;whiteList["perspective-origin"]=false;whiteList["pitch"]=false;whiteList["pitch-range"]=false;whiteList["play-during"]=false;whiteList["position"]=false;whiteList["presentation-level"]=false;whiteList["quotes"]=false;whiteList["region-fragment"]=false;whiteList["resize"]=false;whiteList["rest"]=false;whiteList["rest-after"]=false;whiteList["rest-before"]=false;whiteList["richness"]=false;whiteList["right"]=false;whiteList["rotation"]=false;whiteList["rotation-point"]=false;whiteList["ruby-align"]=false;whiteList["ruby-merge"]=false;whiteList["ruby-position"]=false;whiteList["shape-image-threshold"]=false;whiteList["shape-outside"]=false;whiteList["shape-margin"]=false;whiteList["size"]=false;whiteList["speak"]=false;whiteList["speak-as"]=false;whiteList["speak-header"]=false;whiteList["speak-numeral"]=false;whiteList["speak-punctuation"]=false;whiteList["speech-rate"]=false;whiteList["stress"]=false;whiteList["string-set"]=false;whiteList["tab-size"]=false;whiteList["table-layout"]=false;whiteList["text-align"]=true;whiteList["text-align-last"]=true;whiteList["text-combine-upright"]=true;whiteList["text-decoration"]=true;whiteList["text-decoration-color"]=true;whiteList["text-decoration-line"]=true;whiteList["text-decoration-skip"]=true;whiteList["text-decoration-style"]=true;whiteList["text-emphasis"]=true;whiteList["text-emphasis-color"]=true;whiteList["text-emphasis-position"]=true;whiteList["text-emphasis-style"]=true;whiteList["text-height"]=true;whiteList["text-indent"]=true;whiteList["text-justify"]=true;whiteList["text-orientation"]=true;whiteList["text-overflow"]=true;whiteList["text-shadow"]=true;whiteList["text-space-collapse"]=true;whiteList["text-transform"]=true;whiteList["text-underline-position"]=true;whiteList["text-wrap"]=true;whiteList["top"]=false;whiteList["transform"]=false;whiteList["transform-origin"]=false;whiteList["transform-style"]=false;whiteList["transition"]=false;whiteList["transition-delay"]=false;whiteList["transition-duration"]=false;whiteList["transition-property"]=false;whiteList["transition-timing-function"]=false;whiteList["unicode-bidi"]=false;whiteList["vertical-align"]=false;whiteList["visibility"]=false;whiteList["voice-balance"]=false;whiteList["voice-duration"]=false;whiteList["voice-family"]=false;whiteList["voice-pitch"]=false;whiteList["voice-range"]=false;whiteList["voice-rate"]=false;whiteList["voice-stress"]=false;whiteList["voice-volume"]=false;whiteList["volume"]=false;whiteList["white-space"]=false;whiteList["widows"]=false;whiteList["width"]=true;whiteList["will-change"]=false;whiteList["word-break"]=true;whiteList["word-spacing"]=true;whiteList["word-wrap"]=true;whiteList["wrap-flow"]=false;whiteList["wrap-through"]=false;whiteList["writing-mode"]=false;whiteList["z-index"]=false;return whiteList}function onAttr(name,value,options){}function onIgnoreAttr(name,value,options){}exports.whiteList=getDefaultWhiteList();exports.getDefaultWhiteList=getDefaultWhiteList;exports.onAttr=onAttr;exports.onIgnoreAttr=onIgnoreAttr},{}],8:[function(require,module,exports){var DEFAULT=require("./default");var FilterCSS=require("./css");function filterCSS(html,options){var xss=new FilterCSS(options);return xss.process(html)}exports=module.exports=filterCSS;exports.FilterCSS=FilterCSS;for(var i in DEFAULT)exports[i]=DEFAULT[i];if(typeof window!=="undefined"){window.filterCSS=module.exports}},{"./css":6,"./default":7}],9:[function(require,module,exports){var _=require("./util");function parseStyle(css,onAttr){css=_.trimRight(css);if(css[css.length-1]!==";")css+=";";var cssLength=css.length;var isParenthesisOpen=false;var lastPos=0;var i=0;var retCSS="";function addNewAttr(){if(!isParenthesisOpen){var source=_.trim(css.slice(lastPos,i));var j=source.indexOf(":");if(j!==-1){var name=_.trim(source.slice(0,j));var value=_.trim(source.slice(j+1));if(name){var ret=onAttr(lastPos,retCSS.length,name,value,source);if(ret)retCSS+=ret+"; "}}}lastPos=i+1}for(;i <% } %> + From 0be342c44d5b6287c67922758f076e7897f6c3a8 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sat, 8 Oct 2016 19:58:26 +0800 Subject: [PATCH 08/54] Fix mutiple socket.on handling --- public/js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/index.js b/public/js/index.js index 90a3daf..dff278c 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -2250,7 +2250,7 @@ var socket = io.connect({ var on = socket.on; socket.on = function () { if (!checkLoginStateChanged() && !needRefresh) - on.apply(socket, arguments); + return on.apply(socket, arguments); }; var emit = socket.emit; socket.emit = function () { From 963a435ae1e9248b42b4665acf106dcffa549678 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sat, 8 Oct 2016 20:02:30 +0800 Subject: [PATCH 09/54] Resolve dependency module requiring * es5 style module exports * remove script tag require * webpack config ProvidePlugin Note that this commit only fix JavaScript module loading runtime error. --- package.json | 2 ++ public/js/extra.js | 77 ++++++++++++++++++++++++++++------------- public/js/history.js | 16 ++++++++- public/js/index.js | 59 ++++++++++++++++++++++++------- public/js/pretty.js | 19 +++++++++- public/js/render.js | 6 +++- public/js/syncscroll.js | 39 +++++++++++++-------- public/views/foot.ejs | 9 +++-- webpack.config.js | 7 +++- 9 files changed, 175 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index 5c71cd0..3c7304e 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "morgan": "^1.7.0", "mysql": "^2.11.1", "node-uuid": "^1.4.7", + "ot": "0.0.15", "passport": "^0.3.2", "passport-dropbox-oauth2": "^1.1.0", "passport-facebook": "^2.1.1", @@ -84,6 +85,7 @@ "sequelize-cli": "^2.4.0", "shortid": "2.2.6", "socket.io": "1.4.8", + "socket.io-client": "^1.4.8", "sqlite3": "^3.1.4", "store": "^1.3.20", "string": "^3.3.1", diff --git a/public/js/extra.js b/public/js/extra.js index 77f298f..c6a0f43 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -224,7 +224,7 @@ function finishView(view) { }); //emojify try { - emojify.run(view[0]); + emojify.run(view[0]); } catch (err) { console.warn(err); } @@ -245,12 +245,12 @@ function finishView(view) { try { var $value = $(value); var $ele = $(value).parent().parent(); - + var sequence = $value; sequence.sequenceDiagram({ theme: 'simple' }); - + $ele.addClass('sequence-diagram'); $value.children().unwrap().unwrap(); var svg = $ele.find('> svg'); @@ -266,7 +266,7 @@ function finishView(view) { try { var $value = $(value); var $ele = $(value).parent().parent(); - + var chart = flowchart.parse($value.text()); $value.html(''); chart.drawSVG(value, { @@ -275,7 +275,7 @@ function finishView(view) { 'font-size': '16px', 'font-family': "'Andale Mono', monospace" }); - + $ele.addClass('flow-chart'); $value.children().unwrap().unwrap(); } catch (err) { @@ -288,10 +288,10 @@ function finishView(view) { try { var $value = $(value); var $ele = $(value).parent().parent(); - + var graphviz = Viz($value.text()); $value.html(graphviz); - + $ele.addClass('graphviz'); $value.children().unwrap().unwrap(); } catch (err) { @@ -304,12 +304,12 @@ function finishView(view) { try { var $value = $(value); var $ele = $(value).parent().parent(); - + var mermaidError = null; mermaid.parseError = function (err, hash) { mermaidError = err; }; - + if (mermaidAPI.parse($value.text())) { $ele.addClass('mermaid'); $ele.html($value.text()); @@ -489,6 +489,8 @@ function exportToRawHTML(view) { saveAs(blob, filename); } +var common = require('./common.js'); +var serverurl = common.serverurl; //extract markdown body to html and compile to template function exportToHTML(view) { var title = renderTitle(ui.area.markdown); @@ -794,7 +796,10 @@ emojify.setConfig({ ignore_emoticons: true }); -var md = window.markdownit('default', { +var markdownit = require('markdown-it'); +var markdownitContainer = require('markdown-it-container'); + +var md = markdownit('default', { html: true, breaks: true, langPrefix: "", @@ -802,25 +807,27 @@ var md = window.markdownit('default', { typographer: true, highlight: highlightRender }); -md.use(window.markdownitAbbr); -md.use(window.markdownitFootnote); -md.use(window.markdownitDeflist); -md.use(window.markdownitMark); -md.use(window.markdownitIns); -md.use(window.markdownitSub); -md.use(window.markdownitSup); -md.use(window.markdownitMathjax); -md.use(window.markdownitImsize); + +md.use(require('markdown-it-abbr')); +md.use(require('markdown-it-footnote')); +md.use(require('markdown-it-deflist')); +md.use(require('markdown-it-mark')); +md.use(require('markdown-it-ins')); +md.use(require('markdown-it-sub')); +md.use(require('markdown-it-sup')); +md.use(require('markdown-it-mathjax')); +md.use(require('markdown-it-imsize')); + function renderContainer(tokens, idx, options, env, self) { tokens[idx].attrJoin('role', 'alert'); tokens[idx].attrJoin('class', 'alert'); tokens[idx].attrJoin('class', 'alert-' + tokens[idx].info.trim()); return self.renderToken.apply(self, arguments); } -md.use(window.markdownitContainer, 'success', { render: renderContainer }); -md.use(window.markdownitContainer, 'info', { render: renderContainer }); -md.use(window.markdownitContainer, 'warning', { render: renderContainer }); -md.use(window.markdownitContainer, 'danger', { render: renderContainer }); +md.use(markdownitContainer, 'success', { render: renderContainer }); +md.use(markdownitContainer, 'info', { render: renderContainer }); +md.use(markdownitContainer, 'warning', { render: renderContainer }); +md.use(markdownitContainer, 'danger', { render: renderContainer }); md.renderer.rules.image = function (tokens, idx, options, env, self) { tokens[idx].attrJoin('class', 'raw'); @@ -865,6 +872,9 @@ md.renderer.rules.fence = function (tokens, idx, options, env, self) { + '\n'; }; +/* Defined regex markdown it plugins */ +var Plugin = require('markdown-it-regexp'); + //youtube var youtubePlugin = new Plugin( // regexp to match @@ -1011,4 +1021,23 @@ md.use(gistPlugin); md.use(tocPlugin); md.use(slidesharePlugin); md.use(speakerdeckPlugin); -md.use(pdfPlugin); \ No newline at end of file +md.use(pdfPlugin); + +module.exports = { + md: md, + createtime: createtime, + lastchangetime: lastchangetime, + updateLastChange: updateLastChange, + lastchangeui: lastchangeui, + lastchangeuser: lastchangeuser, + postProcess: postProcess, + finishView: finishView, + autoLinkify: autoLinkify, + deduplicatedHeaderId: deduplicatedHeaderId, + renderTOC: renderTOC, + renderTitle: renderTitle, + renderFilename: renderFilename, + generateToc: generateToc, + smoothHashScroll: smoothHashScroll, + scrollToHash: scrollToHash +}; diff --git a/public/js/history.js b/public/js/history.js index 0840580..fbf71db 100644 --- a/public/js/history.js +++ b/public/js/history.js @@ -1,3 +1,13 @@ +var store = require('store'); + +var common = require('./common'); +var checkIfAuth = common.checkIfAuth; +var urlpath = common.urlpath; + +var extra = require('./extra'); +var renderFilename = extra.renderFilename; +var md = extra.md; + var migrateHistoryFromTempCallback = null; migrateHistoryFromTemp(); @@ -365,4 +375,8 @@ function parseToHistory(list, notehistory, callback) { } } callback(list, notehistory); -} \ No newline at end of file +} + +module.exports = { + writeHistory: writeHistory +} diff --git a/public/js/index.js b/public/js/index.js index dff278c..3801eea 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -18,15 +18,14 @@ require('bootstrap'); require('codemirror/keymap/vim'); require('codemirror/keymap/emacs'); require('codemirror/keymap/sublime'); - -require('../vendor/inlineAttachment/inline-attachment'); -require('../vendor/inlineAttachment/codemirror.inline-attachment'); -require('../vendor/codemirror-spell-checker/spell-checker.min'); +require('codemirror/addon/display/panel'); /* operational transformation */ -require('../vendor/ot/ot.min'); +require('ot/lib/socketio-adapter'); +require('ot/lib/codemirror-adapter'); +require('ot/lib/undo-manager'); +require('../vendor/ot/editor-client'); -/* other vendors plugin */ require('markdown-it'); require('markdown-it-abbr'); require('markdown-it-footnote'); @@ -40,14 +39,13 @@ require('markdown-it-mathjax'); require('markdown-it-regexp'); require('markdown-it-imsize'); +/* other vendors plugin */ require('gist-embed'); -require('lz-string'); require('string'); require('highlight.js'); require('prismjs'); require('prismjs/components/prism-wiki'); require('js-cookie'); -require('emojify.js'); require('to-markdown'); require('raphael'); @@ -63,11 +61,48 @@ require('visibilityjs'); require('list.js'); require('../vendor/md-toc'); require('randomcolor'); -require('keymaster'); var common = require('./common.js'); - +var urlpath = common.urlpath; +var debug = common.debug; +var version = common.version; var serverurl = common.serverurl; +var GOOGLE_API_KEY = common.GOOGLE_API_KEY; +var GOOGLE_CLIENT_ID = common.GOOGLE_CLIENT_ID; +var DROPBOX_APP_KEY = common.DROPBOX_APP_KEY; +var noteurl = common.noteurl; + +var checkLoginStateChanged = common.checkLoginStateChanged; + +var syncScroll = require('./syncscroll'); +var setupSyncAreas = syncScroll.setupSyncAreas; +var clearMap = syncScroll.clearMap; +var syncScrollToEdit = syncScroll.syncScrollToEdit; + +var extra = require('./extra'); +var md = extra.md; +var createtime = extra.createtime; +var updateLastChange = extra.updateLastChange; +var postProcess = extra.postProcess; +var finishView = extra.finishView; +var lastchangetime = extra.lastchangetime; +var autoLinkify = extra.autoLinkify; +var generateToc = extra.generateToc; +var smoothHashScroll = extra.smoothHashScroll; +var lastchangeuser = extra.lastchangeuser; +var deduplicatedHeaderId = extra.deduplicatedHeaderId; +var renderTOC = extra.renderTOC; +var renderTitle = extra.renderTitle; +var renderFilename = extra.renderFilename; +var scrollToHash = extra.scrollToHash; + +var history = require('./history'); +var writeHistory = history.writeHistory; + +var pretty = require('./pretty'); + +var renderer = require('./render'); +var preventXSS = renderer.preventXSS; var defaultTextHeight = 20; var viewportMargin = 20; @@ -349,7 +384,7 @@ var supportExtraTags = [ } } ]; -var modeType = { +window.modeType = { edit: { name: "edit" }, @@ -389,7 +424,7 @@ var visibleSM = false; var visibleMD = false; var visibleLG = false; var isTouchDevice = 'ontouchstart' in document.documentElement; -var currentMode = defaultMode; +window.currentMode = defaultMode; var currentStatus = statusType.offline; var lastInfo = { needRestore: false, diff --git a/public/js/pretty.js b/public/js/pretty.js index 0ca7ee1..ebdec2a 100644 --- a/public/js/pretty.js +++ b/public/js/pretty.js @@ -1,3 +1,16 @@ +var extra = require('./extra') +var md = extra.md; +var finishView = extra.finishView; +var autoLinkify = extra.autoLinkify; +var deduplicatedHeaderId = extra.deduplicatedHeaderId; +var renderTOC = extra.renderTOC; +var generateToc = extra.generateToc; +var smoothHashScroll = extra.smoothHashScroll; +var postProcess = extra.postProcess; +var lastchangeui = extra.lastchangeui; +var updateLastChange = extra.updateLastChange; +var preventXSS = require('./render').preventXSS; + var markdown = $(".markdown-body"); var text = $('