From 2fc6e499c0a9ab552a21fe35123fa2e1a71c8244 Mon Sep 17 00:00:00 2001 From: Yannick Reekmans Date: Tue, 2 Apr 2019 09:25:26 +0000 Subject: [PATCH] Add v2.19.2 --- Gruntfile.js | 6 ++- content/themes/casper/default.hbs | 2 +- content/themes/casper/package.json | 2 +- ...irror-a9780c48171ab93ede6b320f9fe27c80.js} | 2 +- ...st.min-a8ab0ab912a793319197ba23bc890afd.js | 2 +- core/server/helpers/body_class.js | 38 +++++++++---------- core/server/helpers/content.js | 25 ++++++------ core/server/helpers/date.js | 20 +++++----- .../shared/middlewares/custom-redirects.js | 22 ++++------- .../web/shared/middlewares/error-handler.js | 4 +- package.json | 4 +- yarn.lock | 34 +++++++++-------- 12 files changed, 80 insertions(+), 81 deletions(-) rename core/built/assets/codemirror/{codemirror-fd157cf5e83a4eefb22a2df3562c6ae7.js => codemirror-a9780c48171ab93ede6b320f9fe27c80.js} (99%) diff --git a/Gruntfile.js b/Gruntfile.js index 911dae6347..ef815c66fa 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -70,7 +70,8 @@ const configureGrunt = function (grunt) { 'content/themes/casper/assets/js/*.js' ], options: { - livereload: true + livereload: true, + interval: 500 } }, express: { @@ -84,7 +85,8 @@ const configureGrunt = function (grunt) { tasks: ['express:dev'], options: { spawn: false, - livereload: true + livereload: true, + interval: 500 } } }, diff --git a/content/themes/casper/default.hbs b/content/themes/casper/default.hbs index c3304f9d70..97ecf79765 100644 --- a/content/themes/casper/default.hbs +++ b/content/themes/casper/default.hbs @@ -1,5 +1,5 @@ - + {{!-- Document Settings --}} diff --git a/content/themes/casper/package.json b/content/themes/casper/package.json index 7e74482c10..e966763052 100644 --- a/content/themes/casper/package.json +++ b/content/themes/casper/package.json @@ -2,7 +2,7 @@ "name": "casper", "description": "The default personal blogging theme for Ghost. Beautiful, minimal and responsive.", "demo": "https://demo.ghost.io", - "version": "2.9.6", + "version": "2.9.7", "engines": { "ghost": ">=2.0.0", "ghost-api": "v2" diff --git a/core/built/assets/codemirror/codemirror-fd157cf5e83a4eefb22a2df3562c6ae7.js b/core/built/assets/codemirror/codemirror-a9780c48171ab93ede6b320f9fe27c80.js similarity index 99% rename from core/built/assets/codemirror/codemirror-fd157cf5e83a4eefb22a2df3562c6ae7.js rename to core/built/assets/codemirror/codemirror-a9780c48171ab93ede6b320f9fe27c80.js index a417456e08..911580f88c 100644 --- a/core/built/assets/codemirror/codemirror-fd157cf5e83a4eefb22a2df3562c6ae7.js +++ b/core/built/assets/codemirror/codemirror-a9780c48171ab93ede6b320f9fe27c80.js @@ -1262,7 +1262,7 @@ if(e.form&&(tt(e.form,"submit",n),!t.leaveSubmitMethodAlone)){var o=e.form i=o.submit try{var a=o.submit=function(){n(),o.submit=i,o.submit(),o.submit=a}}catch(e){}}t.finishInit=function(t){t.save=n,t.getTextArea=function(){return e},t.toTextArea=function(){t.toTextArea=isNaN,n(),e.parentNode.removeChild(t.getWrapperElement()),e.style.display="",e.form&&(nt(e.form,"submit",n),"function"==typeof e.form.submit&&(e.form.submit=i))}},e.style.display="none" var l=xa(function(t){return e.parentNode.insertBefore(t,e.nextSibling)},t) -return l},function(e){e.off=nt,e.on=tt,e.wheelEventPixels=mi,e.Doc=To,e.splitLines=xt,e.countColumn=F,e.findColumn=q,e.isWordChar=ee,e.Pass=V,e.signal=it,e.Line=$t,e.changeEnd=ki,e.scrollbarModel=Rn,e.Pos=me,e.cmpPos=ve,e.modes=Lt,e.mimeModes=Tt,e.resolveMode=Mt,e.getMode=Nt,e.modeExtensions=At,e.extendMode=Ot,e.copyState=Dt,e.startState=zt,e.innerMode=Wt,e.commands=Xo,e.keyMap=Eo,e.keyName=Ko,e.isModifierKey=jo,e.lookupKey=Bo,e.normalizeKeyMap=Ro,e.StringStream=Pt,e.SharedTextMarker=ko,e.TextMarker=wo,e.LineWidget=vo,e.e_preventDefault=ut,e.e_stopPropagation=ct,e.e_stop=ft,e.addClass=z,e.contains=D,e.rmClass=T,e.keyNames=zo}(xa),xa.version="5.44.0",xa}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict" +return l},function(e){e.off=nt,e.on=tt,e.wheelEventPixels=mi,e.Doc=To,e.splitLines=xt,e.countColumn=F,e.findColumn=q,e.isWordChar=ee,e.Pass=V,e.signal=it,e.Line=$t,e.changeEnd=ki,e.scrollbarModel=Rn,e.Pos=me,e.cmpPos=ve,e.modes=Lt,e.mimeModes=Tt,e.resolveMode=Mt,e.getMode=Nt,e.modeExtensions=At,e.extendMode=Ot,e.copyState=Dt,e.startState=zt,e.innerMode=Wt,e.commands=Xo,e.keyMap=Eo,e.keyName=Ko,e.isModifierKey=jo,e.lookupKey=Bo,e.normalizeKeyMap=Ro,e.StringStream=Pt,e.SharedTextMarker=ko,e.TextMarker=wo,e.LineWidget=vo,e.e_preventDefault=ut,e.e_stopPropagation=ct,e.e_stop=ft,e.addClass=z,e.contains=D,e.rmClass=T,e.keyNames=zo}(xa),xa.version="5.45.0",xa}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict" function t(e){for(var t={},r=0;r{},update:()=>{},_value:(0,t.default)("value"),didReceiveAttrs(){null===this._value&&this.set("_value","")},didInsertElement(){this._super(...arguments),this.initCodeMirror.perform()},willDestroyElement(){if(this._super(...arguments),this._editor){let e=this._editor.getWrapperElement() e.parentNode.removeChild(e),this._editor=null}},actions:{updateFromTextarea(e){this.update(e)}},initCodeMirror:(0,s.task)(function*(){let e=this.lazyLoader -yield e.loadScript("codemirror","assets/codemirror/codemirror-fd157cf5e83a4eefb22a2df3562c6ae7.js"),Ember.run.scheduleOnce("afterRender",this,this._initCodeMirror)}),_initCodeMirror(){let e=this.getProperties("lineNumbers","lineWrapping","indentUnit","mode","theme","autofocus") +yield e.loadScript("codemirror","assets/codemirror/codemirror-a9780c48171ab93ede6b320f9fe27c80.js"),Ember.run.scheduleOnce("afterRender",this,this._initCodeMirror)}),_initCodeMirror(){let e=this.getProperties("lineNumbers","lineWrapping","indentUnit","mode","theme","autofocus") Ember.assign(e,{value:this._value}) let t=this.element.querySelector("textarea") t&&t===document.activeElement&&(e.autofocus=!0),this._editor=new CodeMirror.fromTextArea(t,e),e.autofocus&&this._editor.setCursor(this._editor.lineCount(),0),this._setupCodeMirrorEventHandler("focus",this,this._focus),this._setupCodeMirrorEventHandler("blur",this,this._blur),this._setupCodeMirrorEventHandler("change",this,this._update)},_setupCodeMirrorEventHandler(e,t,s){let n=Ember.run.bind(t,s) diff --git a/core/server/helpers/body_class.js b/core/server/helpers/body_class.js index 09f2ac8ece..e73ad9d85d 100644 --- a/core/server/helpers/body_class.js +++ b/core/server/helpers/body_class.js @@ -2,11 +2,9 @@ // Usage: `{{body_class}}` // // Output classes for the body element -var proxy = require('./proxy'), - _ = require('lodash'), - SafeString = proxy.SafeString; +const {SafeString} = require('./proxy'); -// We use the name body_class to match the helper for consistency: +// We use the name body_class to match the helper for consistency module.exports = function body_class(options) { // eslint-disable-line camelcase let classes = []; const context = options.data.root.context; @@ -14,37 +12,35 @@ module.exports = function body_class(options) { // eslint-disable-line camelcase const tags = obj && obj.tags ? obj.tags : []; const isPage = !!(obj && obj.page); - if (_.includes(context, 'home')) { + if (context.includes('home')) { classes.push('home-template'); - } else if (_.includes(context, 'post') && obj) { + } else if (context.includes('post') && obj) { classes.push('post-template'); - } else if (_.includes(context, 'page') && obj && isPage) { + } else if (context.includes('page') && obj && isPage) { classes.push('page-template'); - classes.push('page-' + obj.slug); - } else if (_.includes(context, 'tag') && this.tag) { + classes.push(`page-${obj.slug}`); + } else if (context.includes('tag') && this.tag) { classes.push('tag-template'); - classes.push('tag-' + this.tag.slug); - } else if (_.includes(context, 'author') && this.author) { + classes.push(`tag-${this.tag.slug}`); + } else if (context.includes('author') && this.author) { classes.push('author-template'); - classes.push('author-' + this.author.slug); - } else if (_.includes(context, 'private')) { + classes.push(`author-${this.author.slug}`); + } else if (context.includes('private')) { classes.push('private-template'); } if (tags) { - classes = classes.concat(tags.map(function (tag) { - return 'tag-' + tag.slug; - })); + classes = classes.concat( + tags.map(({slug}) => `tag-${slug}`) + ); } - if (_.includes(context, 'paged')) { + if (context.includes('paged')) { classes.push('paged'); } - classes = _.reduce(classes, function (memo, item) { - return memo + ' ' + item; - }, ''); + classes = classes.join(' ').trim(); - return new SafeString(classes.trim()); + return new SafeString(classes); }; diff --git a/core/server/helpers/content.js b/core/server/helpers/content.js index af22a59a4d..4cf71ed679 100644 --- a/core/server/helpers/content.js +++ b/core/server/helpers/content.js @@ -6,23 +6,26 @@ // // Enables tag-safe truncation of content by characters or words. -var proxy = require('./proxy'), - _ = require('lodash'), - downsize = require('downsize'), - SafeString = proxy.SafeString; +const {SafeString} = require('./proxy'); +const downsize = require('downsize'); -module.exports = function content(options) { - var truncateOptions = (options || {}).hash || {}; - truncateOptions = _.pick(truncateOptions, ['words', 'characters']); - _.keys(truncateOptions).map(function (key) { - truncateOptions[key] = parseInt(truncateOptions[key], 10); - }); +module.exports = function content(options = {}) { + const hash = options.hash || {}; + const truncateOptions = {}; + let runTruncate = false; + + for (const key of ['words', 'characters']) { + if (hash.hasOwnProperty(key)) { + runTruncate = true; + truncateOptions[key] = parseInt(hash[key], 10); + } + } if (this.html === null) { this.html = ''; } - if (truncateOptions.hasOwnProperty('words') || truncateOptions.hasOwnProperty('characters')) { + if (runTruncate) { return new SafeString( downsize(this.html, truncateOptions) ); diff --git a/core/server/helpers/date.js b/core/server/helpers/date.js index ae059a3249..1cabcb16fc 100644 --- a/core/server/helpers/date.js +++ b/core/server/helpers/date.js @@ -3,13 +3,11 @@ // // Formats a date using moment-timezone.js. Formats published_at by default but will also take a date as a parameter -var proxy = require('./proxy'), - moment = require('moment-timezone'), - SafeString = proxy.SafeString, - i18n = proxy.i18n; +const {SafeString, i18n} = require('./proxy'); +const moment = require('moment-timezone'); module.exports = function (date, options) { - var timezone, format, timeago, timeNow, dateMoment; + let timezone; if (!options && date.hasOwnProperty('hash')) { options = date; @@ -23,18 +21,20 @@ module.exports = function (date, options) { } } + const { + format = 'MMM DD, YYYY', + timeago + } = options.hash; + // ensure that context is undefined, not null, as that can cause errors date = date === null ? undefined : date; - - format = options.hash.format || 'MMM DD, YYYY'; - timeago = options.hash.timeago; timezone = options.data.blog.timezone; - timeNow = moment().tz(timezone); + const timeNow = moment().tz(timezone); // i18n: Making dates, including month names, translatable to any language. // Documentation: http://momentjs.com/docs/#/i18n/ // Locales: https://github.com/moment/moment/tree/develop/locale - dateMoment = moment(date); + const dateMoment = moment(date); dateMoment.locale(i18n.locale()); if (timeago) { diff --git a/core/server/web/shared/middlewares/custom-redirects.js b/core/server/web/shared/middlewares/custom-redirects.js index cdc19087c2..02966000be 100644 --- a/core/server/web/shared/middlewares/custom-redirects.js +++ b/core/server/web/shared/middlewares/custom-redirects.js @@ -22,13 +22,6 @@ _private.registerRoutes = () => { validation.validateRedirects(redirects); redirects.forEach((redirect) => { - /** - * Extract target info, such as hash. - * - * Required to re-formulate the correct endpoint. - */ - const parsedTo = url.parse(redirect.to); - /** * Detect case insensitive modifier when regex is enclosed by * / ... /i @@ -56,17 +49,18 @@ _private.registerRoutes = () => { debug('register', redirect.from); customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) { - const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0, - parsedUrl = url.parse(req.originalUrl); + const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0; + const fromURL = url.parse(req.originalUrl); + const toURL = url.parse(redirect.to); + + toURL.pathname = fromURL.pathname.replace(new RegExp(redirect.from, options), toURL.pathname), + toURL.search = fromURL.search; res.set({ 'Cache-Control': `public, max-age=${maxAge}` }); - res.redirect(redirect.permanent ? 301 : 302, url.format({ - pathname: parsedUrl.pathname.replace(new RegExp(redirect.from, options), parsedTo.pathname), - search: parsedUrl.search, - hash: parsedTo.hash - })); + + res.redirect(redirect.permanent ? 301 : 302, url.format(toURL)); }); }); } catch (err) { diff --git a/core/server/web/shared/middlewares/error-handler.js b/core/server/web/shared/middlewares/error-handler.js index 928e9eb8bb..ba0f814a3b 100644 --- a/core/server/web/shared/middlewares/error-handler.js +++ b/core/server/web/shared/middlewares/error-handler.js @@ -168,7 +168,7 @@ _private.ThemeErrorRenderer = (err, req, res, next) => { // It can be that something went wrong with the theme or otherwise loading handlebars // This ensures that no matter what res.render will work here // @TODO: split the error handler for assets, admin & theme to refactor this away - if (!req.app.engines || Object.keys(req.app.engines).length === 0) { + if (_.isEmpty(req.app.engines)) { res._template = 'error'; req.app.engine('hbs', _private.createHbsEngine()); req.app.set('view engine', 'hbs'); @@ -201,7 +201,7 @@ _private.HTMLErrorRenderer = (err, req, res, next) => { // eslint-disable-line n // e.g. if you serve the admin /ghost and Ghost returns a 503 because it generates the urls at the moment. // This ensures that no matter what res.render will work here // @TODO: put to prepare error function? - if (!req.app.engines || req.app.engines.length === 0) { + if (_.isEmpty(req.app.engines)) { res._template = 'error'; req.app.engine('hbs', _private.createHbsEngine()); req.app.set('view engine', 'hbs'); diff --git a/package.json b/package.json index f63c2a069b..b9f8e10ec0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghost", - "version": "2.19.1", + "version": "2.19.2", "description": "The professional publishing platform", "author": "Ghost Foundation", "homepage": "https://ghost.org", @@ -71,7 +71,7 @@ "ghost-storage-base": "0.0.3", "glob": "5.0.15", "got": "8.3.2", - "gscan": "2.2.1", + "gscan": "2.4.0", "html-to-text": "4.0.0", "image-size": "0.6.3", "intl": "1.2.5", diff --git a/yarn.lock b/yarn.lock index 1610487113..a71c643475 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2361,9 +2361,9 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -ghost-ignition@2.9.2: - version "2.9.2" - resolved "https://registry.yarnpkg.com/ghost-ignition/-/ghost-ignition-2.9.2.tgz#e68de88fa4a20fc09c833fe3278bdc20dca6d525" +ghost-ignition@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ghost-ignition/-/ghost-ignition-3.0.0.tgz#fed40b40cc71f83ed1ea74429ac8071df38fdf68" dependencies: bunyan "1.8.12" bunyan-loggly "^1.3.1" @@ -2378,9 +2378,10 @@ ghost-ignition@2.9.2: prettyjson "^1.1.3" uuid "^3.0.0" -ghost-ignition@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ghost-ignition/-/ghost-ignition-3.0.0.tgz#fed40b40cc71f83ed1ea74429ac8071df38fdf68" +ghost-ignition@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/ghost-ignition/-/ghost-ignition-3.0.2.tgz#a74480c337b917c9350ed0c34dfbd13cac24accd" + integrity sha512-plTyR1tTxv0uGzRkkyatsuhK/eYJaDlRAISd7DMc8l675yc0FH/A9ji6jjCtpP+00+Av5geKee6zpCVtH0uW8Q== dependencies: bunyan "1.8.12" bunyan-loggly "^1.3.1" @@ -2740,9 +2741,10 @@ grunt@1.0.3: path-is-absolute "~1.0.0" rimraf "~2.6.2" -gscan@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/gscan/-/gscan-2.2.1.tgz#38bc8597f7579ab0a0b5b023cf59f71b43f567b0" +gscan@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/gscan/-/gscan-2.4.0.tgz#73d9873f4561c8b00366143f1bba17d865d09e0e" + integrity sha512-lTfYQdBEsJS6ZEc60p0CTzyYDXOU30XPqX3OI3dTLP9GtMgJSSvRaJoUz/yYb84pu441Hy4wnwpOuX1Y4cw66A== dependencies: "@tryghost/extract-zip" "1.6.6" bluebird "^3.4.6" @@ -2751,12 +2753,13 @@ gscan@2.2.1: express "^4.16.2" express-hbs "^1.0.3" fs-extra "^0.26.2" - ghost-ignition "2.9.2" + ghost-ignition "3.0.2" glob "^7.0.5" - lodash "4.17.10" + lodash "^4.17.11" multer "^1.1.0" require-dir "^0.3.2" semver "^5.3.0" + upath "^1.1.0" uuid "^3.0.0" validator "^6.3.0" @@ -3849,10 +3852,6 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@4.17.10: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - lodash@4.17.11, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -6500,6 +6499,11 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +upath@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"