fixed weird line break bug in FF, moved html sanitization to backend. never trust a submit and a smile
This commit is contained in:
parent
b0cb4d9229
commit
3c410eb1b7
16 changed files with 246 additions and 29494 deletions
|
@ -2,6 +2,7 @@ var express = require('express');
|
||||||
import DateUtils from '../../tools/utilities/DateUtils';
|
import DateUtils from '../../tools/utilities/DateUtils';
|
||||||
import StringUtils from '../../tools/utilities/StringUtils';
|
import StringUtils from '../../tools/utilities/StringUtils';
|
||||||
import * as DataEvent from '../../tools/events/DataEvent';
|
import * as DataEvent from '../../tools/events/DataEvent';
|
||||||
|
import sanitize from 'sanitize-html';
|
||||||
import RightsManager,
|
import RightsManager,
|
||||||
{
|
{
|
||||||
TASK_CREATE,
|
TASK_CREATE,
|
||||||
|
@ -16,16 +17,17 @@ import RightsManager,
|
||||||
OBJECT_POST
|
OBJECT_POST
|
||||||
}
|
}
|
||||||
from '../../tools/utilities/RightsManager';
|
from '../../tools/utilities/RightsManager';
|
||||||
var router = express.Router();
|
const router = express.Router();
|
||||||
var multer = require('multer');
|
const multer = require('multer');
|
||||||
var fs = require('fs-extra');
|
const md = require('markdown-it')('commonmark');
|
||||||
var Models = require('../../models');
|
const fs = require('fs-extra');
|
||||||
|
const Models = require('../../models');
|
||||||
const dateUtils = new DateUtils();
|
const dateUtils = new DateUtils();
|
||||||
const rightsManager = new RightsManager();
|
const rightsManager = new RightsManager();
|
||||||
var uploadPath = "./content/blog-images/" + dateUtils.getDate('year', new Date()) + "/" + dateUtils.getDate('month', new Date());
|
const uploadPath = "./content/blog-images/" + dateUtils.getDate('year', new Date()) + "/" + dateUtils.getDate('month', new Date());
|
||||||
var Sequelize = require('sequelize');
|
const Sequelize = require('sequelize');
|
||||||
const Op = Sequelize.Op;
|
const Op = Sequelize.Op;
|
||||||
var _ = require('lodash');
|
const _ = require('lodash');
|
||||||
fs.ensureDir(uploadPath, function(err)
|
fs.ensureDir(uploadPath, function(err)
|
||||||
{
|
{
|
||||||
//console.log(err) // => null
|
//console.log(err) // => null
|
||||||
|
@ -76,6 +78,23 @@ router.post("/sync", (req, res, next) =>
|
||||||
}
|
}
|
||||||
}).then(found =>
|
}).then(found =>
|
||||||
{
|
{
|
||||||
|
let buffed = sanitize(item.post.plaintext,
|
||||||
|
{
|
||||||
|
allowedTags: ['del', 'a', 'iframe', 'img', ],
|
||||||
|
allowedAttributes:
|
||||||
|
{
|
||||||
|
a: ['href', 'name', 'target'],
|
||||||
|
img: ['src'],
|
||||||
|
iframe: ['height', 'width', 'src', 'frameborder', 'allow', 'allowfullscreen']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
buffed = new StringUtils().decodeHTML(buffed);
|
||||||
|
item.post.plaintext = buffed;
|
||||||
|
item.post.html = md.render(buffed,
|
||||||
|
{
|
||||||
|
html: true,
|
||||||
|
xhtmlOut: true,
|
||||||
|
})
|
||||||
if (!_.isEqual(item.post, found.post))
|
if (!_.isEqual(item.post, found.post))
|
||||||
{
|
{
|
||||||
found.update(item).then(updated =>
|
found.update(item).then(updated =>
|
||||||
|
@ -122,16 +141,17 @@ router.get('/json', function(req, res, next)
|
||||||
}).then(function(posts)
|
}).then(function(posts)
|
||||||
{
|
{
|
||||||
let newlist = [];
|
let newlist = [];
|
||||||
|
for (let index = 0; index < posts.length; index++)
|
||||||
for (let index = 0; index < posts.length; index++) {
|
{
|
||||||
let item = posts[index].post;
|
let item = posts[index].post;
|
||||||
if(typeof item.deleted == 'undefined' || item.deleted == false)
|
if (typeof item.deleted == 'undefined' || item.deleted == false)
|
||||||
|
{
|
||||||
|
newlist.push(posts[index])
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
newlist.push(posts[index])
|
|
||||||
}else{
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
res.json(newlist)
|
res.json(newlist)
|
||||||
}).catch(function(err)
|
}).catch(function(err)
|
||||||
|
@ -184,7 +204,6 @@ router.post('/add-post-image', function(req, res, next)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/add-feature-image', function(req, res, next)
|
router.post('/add-feature-image', function(req, res, next)
|
||||||
{
|
{
|
||||||
//console.log(req.body);
|
//console.log(req.body);
|
||||||
|
|
|
@ -116,7 +116,7 @@ router.get('/edit/:id', function(req, res)
|
||||||
{
|
{
|
||||||
[Op.contains]:
|
[Op.contains]:
|
||||||
{
|
{
|
||||||
slug: req.params.id
|
uuid: req.params.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,10 +76,12 @@ class TextEditor extends EventEmitter
|
||||||
{
|
{
|
||||||
var caret = position(this.textEditor).pos;
|
var caret = position(this.textEditor).pos;
|
||||||
var spiffed = hljs.highlight('markdown', this.textEditor.innerText).value;
|
var spiffed = hljs.highlight('markdown', this.textEditor.innerText).value;
|
||||||
|
spiffed = spiffed.replace(new RegExp('\r?\n','g'), '<br>');
|
||||||
var temp = document.createElement("div");
|
var temp = document.createElement("div");
|
||||||
temp.innerText = spiffed;
|
temp.innerText = spiffed;
|
||||||
this.textEditor.innerHTML = temp.innerText;
|
this.textEditor.innerHTML = temp.innerText;
|
||||||
position(this.textEditor, caret)
|
position(this.textEditor, caret)
|
||||||
|
this.textEditor.style.maxWidth = '900px';
|
||||||
}
|
}
|
||||||
notify(type, data)
|
notify(type, data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,6 @@ export default class DBUtils
|
||||||
}).then(updated =>
|
}).then(updated =>
|
||||||
{}).catch(e =>
|
{}).catch(e =>
|
||||||
{
|
{
|
||||||
consol.log("ERROR", e)
|
|
||||||
let err = {
|
let err = {
|
||||||
message: "UPDATE ERROR",
|
message: "UPDATE ERROR",
|
||||||
error: e
|
error: e
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"build-front-kit": "uglifyjs node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/$npm_package_theme/assets/js/toolkit.min.js",
|
"build-front-kit": "uglifyjs node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/$npm_package_theme/assets/js/toolkit.min.js",
|
||||||
"watch-back-scripts": "parcel watch themes/dash/src/com/Start.js --out-dir themes/dash/assets/js --out-file dash.min.js --public-url /dash/assets/js",
|
"watch-back-scripts": "parcel watch themes/dash/src/com/Start.js --out-dir themes/dash/assets/js --out-file dash.min.js --public-url /dash/assets/js",
|
||||||
"watch-back-styles": "stylus -w -m -o themes/dash/assets/css themes/dash/src/styles/dash.styl",
|
"watch-back-styles": "stylus -w -m -o themes/dash/assets/css themes/dash/src/styles/dash.styl",
|
||||||
"build-back-kit": "uglifyjs themes/dash/src/libraries/highlight.pack.js node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/dash/assets/js/dashkit.min.js"
|
"build-back-kit": "uglifyjs themes/dash/src/libraries/highlight.pack.js node_modules/dompurify/dist/purify.min.js node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/dash/assets/js/dashkit.min.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.12.0"
|
"node": ">=8.12.0"
|
||||||
|
|
|
@ -2334,8 +2334,13 @@ select {
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
line-break: normal;
|
line-break: normal;
|
||||||
|
-webkit-line-break: normal;
|
||||||
|
-o-line-break: normal;
|
||||||
|
-moz-line-break: normal;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
overflow-wrap: break-word;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 900px;
|
||||||
}
|
}
|
||||||
.dp-modal {
|
.dp-modal {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
File diff suppressed because one or more lines are too long
29591
themes/dash/assets/js/dash.min.js
vendored
29591
themes/dash/assets/js/dash.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
themes/dash/assets/js/dashkit.min.js
vendored
3
themes/dash/assets/js/dashkit.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -25,7 +25,7 @@
|
||||||
br
|
br
|
||||||
- var index = 0;
|
- var index = 0;
|
||||||
- for ( index; index < items.length; index++)
|
- for ( index; index < items.length; index++)
|
||||||
a(href="/@/dashboard/posts/edit/"+items[index].post.slug id=items[index].post.uuid)
|
a(href="/@/dashboard/posts/edit/"+items[index].post.uuid id=items[index].post.uuid)
|
||||||
= items[index].post.title
|
= items[index].post.title
|
||||||
br
|
br
|
||||||
br
|
br
|
||||||
|
|
|
@ -11,7 +11,7 @@ block main-content
|
||||||
- var index = 0;
|
- var index = 0;
|
||||||
- for ( index; index < items.length; index++)
|
- for ( index; index < items.length; index++)
|
||||||
- var date = new Date(items[index].post.created)
|
- var date = new Date(items[index].post.created)
|
||||||
a.post-list-link(href="/@/dashboard/posts/edit/"+items[index].post.slug id=items[index].post.uuid)
|
a.post-list-link(href="/@/dashboard/posts/edit/"+items[index].post.uuid id=items[index].post.uuid)
|
||||||
= items[index].post.title
|
= items[index].post.title
|
||||||
br
|
br
|
||||||
span= date.getFullYear()+"-"+date.getMonth()+"-"+date.getDate()+" "+date.getHours()+":"+date.getMinutes()
|
span= date.getFullYear()+"-"+date.getMonth()+"-"+date.getDate()+" "+date.getHours()+":"+date.getMinutes()
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default class Base
|
||||||
this.dataUtils = new DataUtils();
|
this.dataUtils = new DataUtils();
|
||||||
this.dbUtils = new DBUtils();
|
this.dbUtils = new DBUtils();
|
||||||
this.settings = [];
|
this.settings = [];
|
||||||
this.cacheAssets();
|
//this.cacheAssets();
|
||||||
this.storeLocalData();
|
this.storeLocalData();
|
||||||
}
|
}
|
||||||
start()
|
start()
|
||||||
|
|
|
@ -8,13 +8,9 @@ import DataUtils,
|
||||||
CONTENT_TYPE_FORM
|
CONTENT_TYPE_FORM
|
||||||
}
|
}
|
||||||
from '../../../../../brain//tools/utilities/DataUtils';
|
from '../../../../../brain//tools/utilities/DataUtils';
|
||||||
import * as DataEvent from '../../../../../brain//tools/events/DataEvent';
|
|
||||||
import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
|
import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
|
||||||
import Dexie from 'dexie';
|
|
||||||
import sanitize from 'sanitize-html' //NOTE: Santize is a really big add - explore ways to reduce this
|
|
||||||
import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
|
import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
|
||||||
import DBUtils from '../../../../../brain/tools/utilities/DBUtils';
|
import DBUtils from '../../../../../brain/tools/utilities/DBUtils';
|
||||||
var md = require('markdown-it')('commonmark');
|
|
||||||
var uuidv4 = require('uuid/v4');
|
var uuidv4 = require('uuid/v4');
|
||||||
export default class PostActions
|
export default class PostActions
|
||||||
{
|
{
|
||||||
|
@ -40,25 +36,11 @@ export default class PostActions
|
||||||
txt.innerHTML = document.getElementById('edit-post-text').innerHTML;
|
txt.innerHTML = document.getElementById('edit-post-text').innerHTML;
|
||||||
let html = txt.value;
|
let html = txt.value;
|
||||||
html = html.replace(/<\/?span[^>]*>/g, ""); //removes highightjs styling
|
html = html.replace(/<\/?span[^>]*>/g, ""); //removes highightjs styling
|
||||||
let buffed = sanitize(html,
|
html = html.replace(/<\/?br[^>]*>/g, "\n"); //convert back to encoded line break for storage
|
||||||
{
|
|
||||||
allowedTags: ['del', 'a', 'iframe', 'img'],
|
|
||||||
allowedAttributes:
|
|
||||||
{
|
|
||||||
a: ['href', 'name', 'target'],
|
|
||||||
img: ['src'],
|
|
||||||
iframe: ['height', 'width', 'src', 'frameborder', 'allow', 'allowfullscreen']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
buffed = new StringUtils().decodeHTML(buffed);
|
|
||||||
data.title = document.getElementById('post_title').value;
|
data.title = document.getElementById('post_title').value;
|
||||||
data.slug = new StringUtils().cleanString(document.getElementById('post_title').value)
|
data.slug = new StringUtils().cleanString(document.getElementById('post_title').value)
|
||||||
data.plaintext = buffed;
|
data.plaintext = html;
|
||||||
data.html = md.render(buffed,
|
data.html = html;
|
||||||
{
|
|
||||||
html: true,
|
|
||||||
xhtmlOut: true,
|
|
||||||
})
|
|
||||||
data.created = document.getElementById('post-date').value;
|
data.created = document.getElementById('post-date').value;
|
||||||
data.tags = document.getElementById('post_tags').value;
|
data.tags = document.getElementById('post_tags').value;
|
||||||
data.page = document.getElementById('option-page').getAttribute('data-active')
|
data.page = document.getElementById('option-page').getAttribute('data-active')
|
||||||
|
@ -79,8 +61,7 @@ export default class PostActions
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (typeof data.feature == 'undefined')
|
if (typeof data.feature == 'undefined') data.feature = ""
|
||||||
data.feature = ""
|
|
||||||
}
|
}
|
||||||
if (id == null)
|
if (id == null)
|
||||||
{
|
{
|
||||||
|
@ -120,13 +101,15 @@ export default class PostActions
|
||||||
deletePost(id, body)
|
deletePost(id, body)
|
||||||
{
|
{
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
body.deleted = new Date().toString();
|
body.deleted = new Date().toString();
|
||||||
return new Promise(function(resolve, reject){
|
return new Promise(function(resolve, reject)
|
||||||
self.dbUtils.archivePost(id, body).then(response=>{
|
{
|
||||||
|
self.dbUtils.archivePost(id, body).then(response =>
|
||||||
|
{
|
||||||
console.log(response)
|
console.log(response)
|
||||||
resolve(response)
|
resolve(response)
|
||||||
}).catch(err=>{
|
}).catch(err =>
|
||||||
|
{
|
||||||
console.log(err)
|
console.log(err)
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,14 +10,16 @@ import DataUtils,
|
||||||
}
|
}
|
||||||
from '../../../../../brain/tools/utilities/DataUtils';
|
from '../../../../../brain/tools/utilities/DataUtils';
|
||||||
import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
|
import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
|
||||||
import Animate from '../../../../../brain/tools/effects/Animate';
|
|
||||||
import PostActions from '../actions/PostActions';
|
import PostActions from '../actions/PostActions';
|
||||||
import * as EditorEvent from '../../../../../brain/tools/events/EditorEvent';
|
import * as EditorEvent from '../../../../../brain/tools/events/EditorEvent';
|
||||||
import TinyDatePicker from 'tiny-date-picker';
|
import TinyDatePicker from 'tiny-date-picker';
|
||||||
import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
|
import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
|
||||||
import TextEditor from '../../../../../brain/tools/ui/TextEditor';
|
import TextEditor from '../../../../../brain/tools/ui/TextEditor';
|
||||||
import Dexie from 'dexie';
|
import DBUtils,
|
||||||
import DBUtils , {COUNT, FINAL_KEY} from '../../../../../brain/tools/utilities/DBUtils';
|
{
|
||||||
|
FINAL_KEY
|
||||||
|
}
|
||||||
|
from '../../../../../brain/tools/utilities/DBUtils';
|
||||||
export default class PostEditor
|
export default class PostEditor
|
||||||
{
|
{
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
@ -26,26 +28,28 @@ export default class PostEditor
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
let self = this;
|
let self = this;
|
||||||
this.anim = new Animate();
|
|
||||||
this.dataUtils = new DataUtils();
|
this.dataUtils = new DataUtils();
|
||||||
this.dateUtils = new DateUtils();
|
this.dateUtils = new DateUtils();
|
||||||
this.urlPieces = document.URL.split("/");
|
this.urlPieces = document.URL.split("/");
|
||||||
this.dbUtils = new DBUtils();
|
this.dbUtils = new DBUtils();
|
||||||
this.post = [];
|
this.post = [];
|
||||||
this.postID = null;
|
this.postID = null;
|
||||||
|
|
||||||
if (document.getElementById('post-edit-index').getAttribute('data-index'))
|
if (document.getElementById('post-edit-index').getAttribute('data-index'))
|
||||||
{
|
{
|
||||||
this.postID = document.getElementById('post-edit-index').getAttribute('data-index');
|
this.postID = document.getElementById('post-edit-index').getAttribute('data-index');
|
||||||
this.dbUtils.getPost(this.postID).then(body=>{
|
this.dbUtils.getPost(this.postID).then(body =>
|
||||||
|
{
|
||||||
self.post = body.post;
|
self.post = body.post;
|
||||||
this.start()
|
this.start()
|
||||||
}).catch(err=>{
|
}).catch(err =>
|
||||||
|
{
|
||||||
//console.log(err)
|
//console.log(err)
|
||||||
})
|
})
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this.start()
|
this.start()
|
||||||
}
|
}
|
||||||
if (document.getElementById('edit-post-text'))
|
if (document.getElementById('edit-post-text'))
|
||||||
{
|
{
|
||||||
this.editor = new TextEditor(document.getElementById('edit-post-text'), document.getElementById('header').offsetHeight + document.getElementById('post-header').offsetHeight + document.getElementById('post-feature').offsetHeight);
|
this.editor = new TextEditor(document.getElementById('edit-post-text'), document.getElementById('header').offsetHeight + document.getElementById('post-header').offsetHeight + document.getElementById('post-feature').offsetHeight);
|
||||||
|
@ -127,10 +131,10 @@ export default class PostEditor
|
||||||
{
|
{
|
||||||
setTimeout(f =>
|
setTimeout(f =>
|
||||||
{
|
{
|
||||||
self.dbUtils.getPost(Number(response.response.newPost)).then(r=>{
|
self.dbUtils.getPost(Number(response.response.newPost)).then(r =>
|
||||||
window.location = "/@/dashboard/posts/edit/" + r.post.slug;
|
{
|
||||||
|
window.location = "/@/dashboard/posts/edit/" + r.post.uuid;
|
||||||
})
|
})
|
||||||
|
|
||||||
}, 100);
|
}, 100);
|
||||||
}).catch(err =>
|
}).catch(err =>
|
||||||
{
|
{
|
||||||
|
@ -152,10 +156,9 @@ export default class PostEditor
|
||||||
new PostActions().deletePost(this.postID, this.post).then((response) =>
|
new PostActions().deletePost(this.postID, this.post).then((response) =>
|
||||||
{
|
{
|
||||||
setTimeout(f =>
|
setTimeout(f =>
|
||||||
{
|
{
|
||||||
window.location = "/@/dashboard/posts/"
|
window.location = "/@/dashboard/posts/"
|
||||||
|
}, 100);
|
||||||
}, 100);
|
|
||||||
}).catch((err) =>
|
}).catch((err) =>
|
||||||
{
|
{
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|
|
@ -199,8 +199,13 @@
|
||||||
word-wrap normal
|
word-wrap normal
|
||||||
white-space pre-wrap
|
white-space pre-wrap
|
||||||
line-break normal
|
line-break normal
|
||||||
|
-webkit-line-break normal
|
||||||
|
-o-line-break normal
|
||||||
|
-moz-line-break normal
|
||||||
display inline-block
|
display inline-block
|
||||||
|
overflow-wrap break-word
|
||||||
width 100%
|
width 100%
|
||||||
|
max-width 900px
|
||||||
|
|
||||||
// TINY DATE
|
// TINY DATE
|
||||||
.dp-modal
|
.dp-modal
|
||||||
|
|
Loading…
Reference in a new issue