mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
🐛 fix: make small media types not stretch (#7265)
no issue Fixes a bug with displaying small media types like images or gif. Two reasons for that: 1. In many cases, we only have the relative URL instead of the absolute URL for the media source and therefore, `Amperize` module wasn't able to detect the image size and set the default image size of `width="600"` and `height="400"`. 2. Even if we have detected the correct image size, the attribute `layout="default"` would still make it strech. This issue is fixed in `Amperize`, but it wasn't merged at this time, so I set the dependency on my fork. Adds `amp-anim` to the `.post-content` class, to have same CSS style as an image.
This commit is contained in:
parent
84a35a4753
commit
93ee19f36e
4 changed files with 155 additions and 135 deletions
|
@ -11,6 +11,8 @@ var hbs = require('express-hbs'),
|
||||||
Amperize = require('amperize'),
|
Amperize = require('amperize'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
sanitizeHtml = require('sanitize-html'),
|
sanitizeHtml = require('sanitize-html'),
|
||||||
|
config = require('../../../../config'),
|
||||||
|
makeAbsoluteUrl = require('../../../../utils/make-absolute-urls'),
|
||||||
amperize = new Amperize(),
|
amperize = new Amperize(),
|
||||||
amperizeCache = {},
|
amperizeCache = {},
|
||||||
allowedAMPTags = [],
|
allowedAMPTags = [],
|
||||||
|
@ -40,6 +42,9 @@ function getAmperizeHTML(html, post) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make relative URLs abolute
|
||||||
|
html = makeAbsoluteUrl(html, config.url, post.url).html();
|
||||||
|
|
||||||
if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) {
|
if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
amperize.parse(html, function (err, res) {
|
amperize.parse(html, function (err, res) {
|
||||||
|
@ -64,7 +69,7 @@ function ampContent() {
|
||||||
return Promise.props(amperizeHTML).then(function (result) {
|
return Promise.props(amperizeHTML).then(function (result) {
|
||||||
ampHTML = result.amperize || '';
|
ampHTML = result.amperize || '';
|
||||||
|
|
||||||
// let's sanitize our html!!!
|
// let's sanitize our HTML!!!
|
||||||
cleanHTML = sanitizeHtml(ampHTML, {
|
cleanHTML = sanitizeHtml(ampHTML, {
|
||||||
allowedTags: allowedAMPTags,
|
allowedTags: allowedAMPTags,
|
||||||
allowedAttributes: false,
|
allowedAttributes: false,
|
||||||
|
|
|
@ -692,7 +692,8 @@
|
||||||
|
|
||||||
/* Keep images centered, and allow images wider than the main
|
/* Keep images centered, and allow images wider than the main
|
||||||
text column to break out. */
|
text column to break out. */
|
||||||
.post-content amp-img {
|
.post-content amp-img,
|
||||||
|
.post-content amp-anim {
|
||||||
/* Centers an image by (1) pushing its left edge to the
|
/* Centers an image by (1) pushing its left edge to the
|
||||||
center of its container and (2) shifting the entire image
|
center of its container and (2) shifting the entire image
|
||||||
in the opposite direction by half its own width.
|
in the opposite direction by half its own width.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
configUtils = require('../../../../test/utils/configUtils'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
ampContentHelper = rewire('../lib/helpers/amp_content');
|
ampContentHelper = rewire('../lib/helpers/amp_content');
|
||||||
|
@ -24,89 +25,6 @@ describe('{{amp_content}} helper', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can render content from cache', function (done) {
|
|
||||||
var testData = {
|
|
||||||
html: 'Hello World',
|
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
ampCachedResult,
|
|
||||||
ampResult = ampContentHelper.call(testData),
|
|
||||||
amperizeCache = ampContentHelper.__get__('amperizeCache');
|
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
|
||||||
should.exist(rendered);
|
|
||||||
should.exist(amperizeCache);
|
|
||||||
rendered.string.should.equal(testData.html);
|
|
||||||
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
|
||||||
amperizeCache[1].should.have.property('amp', testData.html);
|
|
||||||
// call it again, to make it fetch from cache
|
|
||||||
ampCachedResult = ampContentHelper.call(testData);
|
|
||||||
ampCachedResult.then(function (rendered) {
|
|
||||||
should.exist(rendered);
|
|
||||||
should.exist(amperizeCache);
|
|
||||||
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
|
||||||
amperizeCache[1].should.have.property('amp', testData.html);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}).catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fetches new AMP HTML if post was changed', function (done) {
|
|
||||||
var testData1 = {
|
|
||||||
html: 'Hello World',
|
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
testData2 = {
|
|
||||||
html: 'Hello Ghost',
|
|
||||||
updated_at: 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
ampResult = ampContentHelper.call(testData1),
|
|
||||||
amperizeCache = ampContentHelper.__get__('amperizeCache');
|
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
|
||||||
should.exist(rendered);
|
|
||||||
should.exist(amperizeCache);
|
|
||||||
rendered.string.should.equal(testData1.html);
|
|
||||||
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
|
||||||
amperizeCache[1].should.have.property('amp', testData1.html);
|
|
||||||
|
|
||||||
// call it again with different values to fetch from Amperize and not from cache
|
|
||||||
ampResult = ampContentHelper.call(testData2);
|
|
||||||
ampResult.then(function (rendered) {
|
|
||||||
should.exist(rendered);
|
|
||||||
should.exist(amperizeCache);
|
|
||||||
|
|
||||||
// it should not have the old value,
|
|
||||||
amperizeCache[1].should.not.have.property('Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)');
|
|
||||||
// only the new one
|
|
||||||
rendered.string.should.equal(testData2.html);
|
|
||||||
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)');
|
|
||||||
amperizeCache[1].should.have.property('amp', testData2.html);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}).catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sanitizes remaining and not valid tags', function (done) {
|
|
||||||
var testData = {
|
|
||||||
html: '<form<input type="text" placeholder="Hi AMP tester"></form>' +
|
|
||||||
'<script>some script here</script>' +
|
|
||||||
'<style> h1 {color:red;} p {color:blue;}</style>',
|
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
ampResult = ampContentHelper.call(testData);
|
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
|
||||||
should.exist(rendered);
|
|
||||||
rendered.string.should.be.equal('');
|
|
||||||
done();
|
|
||||||
}).catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns if no html is provided', function (done) {
|
it('returns if no html is provided', function (done) {
|
||||||
var testData = {
|
var testData = {
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
@ -121,60 +39,156 @@ describe('{{amp_content}} helper', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can transform img tags to amp-img', function (done) {
|
describe('Cache', function () {
|
||||||
var testData = {
|
it('can render content from cache', function (done) {
|
||||||
html: '<img src="https://ghost.org/images/ghost.png" alt="The Ghost Logo" />',
|
var testData = {
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
html: 'Hello World',
|
||||||
id: 1
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
},
|
id: 1
|
||||||
expectedResult = '<amp-img src="https://ghost.org/images/ghost.png" alt="The Ghost Logo" layout="responsive" width="800" height="400"></amp-img>',
|
},
|
||||||
ampResult = ampContentHelper.call(testData);
|
ampCachedResult,
|
||||||
|
ampResult = ampContentHelper.call(testData),
|
||||||
|
amperizeCache = ampContentHelper.__get__('amperizeCache');
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
ampResult.then(function (rendered) {
|
||||||
should.exist(rendered);
|
should.exist(rendered);
|
||||||
rendered.string.should.equal(expectedResult);
|
should.exist(amperizeCache);
|
||||||
done();
|
rendered.string.should.equal(testData.html);
|
||||||
}).catch(done);
|
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
||||||
|
amperizeCache[1].should.have.property('amp', testData.html);
|
||||||
|
// call it again, to make it fetch from cache
|
||||||
|
ampCachedResult = ampContentHelper.call(testData);
|
||||||
|
ampCachedResult.then(function (rendered) {
|
||||||
|
should.exist(rendered);
|
||||||
|
should.exist(amperizeCache);
|
||||||
|
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
||||||
|
amperizeCache[1].should.have.property('amp', testData.html);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fetches new AMP HTML if post was changed', function (done) {
|
||||||
|
var testData1 = {
|
||||||
|
html: 'Hello World',
|
||||||
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
testData2 = {
|
||||||
|
html: 'Hello Ghost',
|
||||||
|
updated_at: 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
ampResult = ampContentHelper.call(testData1),
|
||||||
|
amperizeCache = ampContentHelper.__get__('amperizeCache');
|
||||||
|
|
||||||
|
ampResult.then(function (rendered) {
|
||||||
|
should.exist(rendered);
|
||||||
|
should.exist(amperizeCache);
|
||||||
|
rendered.string.should.equal(testData1.html);
|
||||||
|
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)');
|
||||||
|
amperizeCache[1].should.have.property('amp', testData1.html);
|
||||||
|
|
||||||
|
// call it again with different values to fetch from Amperize and not from cache
|
||||||
|
ampResult = ampContentHelper.call(testData2);
|
||||||
|
ampResult.then(function (rendered) {
|
||||||
|
should.exist(rendered);
|
||||||
|
should.exist(amperizeCache);
|
||||||
|
|
||||||
|
// it should not have the old value,
|
||||||
|
amperizeCache[1].should.not.have.property('Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)');
|
||||||
|
// only the new one
|
||||||
|
rendered.string.should.equal(testData2.html);
|
||||||
|
amperizeCache[1].should.have.property('updated_at', 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)');
|
||||||
|
amperizeCache[1].should.have.property('amp', testData2.html);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can transform audio tags to amp-audio', function (done) {
|
describe('Transforms and sanitizes HTML', function () {
|
||||||
var testData = {
|
beforeEach(function () {
|
||||||
html: '<audio controls="controls" width="auto" height="50" autoplay="mobile">Your browser does not support the <code>audio</code> element.<source src="foo.wav" type="audio/wav"></audio>' +
|
configUtils.set({url: 'https://my-awesome-blog.com/'});
|
||||||
'<audio src="http://foo.ogg"><track kind="captions" src="http://foo.en.vtt" srclang="en" label="English"><track kind="captions" src="http://foo.sv.vtt" srclang="sv" label="Svenska"></audio>',
|
});
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
expectedResult = '<amp-audio controls="controls" width="auto" height="50" autoplay="mobile">Your browser does not support the <code>audio</code> element.<source src="foo.wav" type="audio/wav" /></amp-audio>' +
|
|
||||||
'<amp-audio src="https://foo.ogg"><track kind="captions" src="https://foo.en.vtt" srclang="en" label="English" /><track kind="captions" src="https://foo.sv.vtt" srclang="sv" label="Svenska" /></amp-audio>',
|
|
||||||
ampResult = ampContentHelper.call(testData);
|
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
afterEach(function () {
|
||||||
should.exist(rendered);
|
ampContentHelper.__set__('amperizeCache', {});
|
||||||
rendered.string.should.equal(expectedResult);
|
configUtils.restore();
|
||||||
done();
|
});
|
||||||
}).catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can handle incomplete HTML tags', function (done) {
|
it('can transform img tags to amp-img', function (done) {
|
||||||
var testData = {
|
var testData = {
|
||||||
html: '<img><///img>',
|
html: '<img src="/content/images/ghost.png" alt="The Ghost Logo" />',
|
||||||
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
id: 1
|
id: 1
|
||||||
},
|
},
|
||||||
ampResult = ampContentHelper.call(testData),
|
expectedResult = '<amp-img src="https://my-awesome-blog.com/content/images/ghost.png" alt="The Ghost Logo" width="600" height="400" layout="responsive"></amp-img>',
|
||||||
sanitizedHTML,
|
ampResult = ampContentHelper.call(testData);
|
||||||
ampedHTML;
|
|
||||||
|
|
||||||
ampResult.then(function (rendered) {
|
ampResult.then(function (rendered) {
|
||||||
sanitizedHTML = ampContentHelper.__get__('cleanHTML');
|
should.exist(rendered);
|
||||||
ampedHTML = ampContentHelper.__get__('ampHTML');
|
rendered.string.should.equal(expectedResult);
|
||||||
should.exist(rendered);
|
done();
|
||||||
rendered.string.should.equal('');
|
}).catch(done);
|
||||||
should.exist(ampedHTML);
|
});
|
||||||
ampedHTML.should.be.equal('<img>');
|
|
||||||
should.exist(sanitizedHTML);
|
it('can transform audio tags to amp-audio', function (done) {
|
||||||
sanitizedHTML.should.be.equal('');
|
var testData = {
|
||||||
done();
|
html: '<audio controls="controls" width="auto" height="50" autoplay="mobile">Your browser does not support the <code>audio</code> element.<source src="https://audio.com/foo.wav" type="audio/wav"></audio>' +
|
||||||
}).catch(done);
|
'<audio src="http://audio.com/foo.ogg"><track kind="captions" src="http://audio.com/foo.en.vtt" srclang="en" label="English"><track kind="captions" src="http://audio.com/foo.sv.vtt" srclang="sv" label="Svenska"></audio>',
|
||||||
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
expectedResult = '<amp-audio controls="controls" width="auto" height="50" autoplay="mobile">Your browser does not support the <code>audio</code> element.<source src="https://audio.com/foo.wav" type="audio/wav" /></amp-audio>' +
|
||||||
|
'<amp-audio src="https://audio.com/foo.ogg"><track kind="captions" src="https://audio.com/foo.en.vtt" srclang="en" label="English" /><track kind="captions" src="https://audio.com/foo.sv.vtt" srclang="sv" label="Svenska" /></amp-audio>',
|
||||||
|
ampResult = ampContentHelper.call(testData);
|
||||||
|
|
||||||
|
ampResult.then(function (rendered) {
|
||||||
|
should.exist(rendered);
|
||||||
|
rendered.string.should.equal(expectedResult);
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can handle incomplete HTML tags', function (done) {
|
||||||
|
var testData = {
|
||||||
|
html: '<img><///img>',
|
||||||
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
ampResult = ampContentHelper.call(testData),
|
||||||
|
sanitizedHTML,
|
||||||
|
ampedHTML;
|
||||||
|
|
||||||
|
ampResult.then(function (rendered) {
|
||||||
|
sanitizedHTML = ampContentHelper.__get__('cleanHTML');
|
||||||
|
ampedHTML = ampContentHelper.__get__('ampHTML');
|
||||||
|
should.exist(rendered);
|
||||||
|
rendered.string.should.equal('');
|
||||||
|
should.exist(ampedHTML);
|
||||||
|
ampedHTML.should.be.equal('<img>');
|
||||||
|
should.exist(sanitizedHTML);
|
||||||
|
sanitizedHTML.should.be.equal('');
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sanitizes remaining and not valid tags', function (done) {
|
||||||
|
var testData = {
|
||||||
|
html: '<form<input type="text" placeholder="Hi AMP tester"></form>' +
|
||||||
|
'<script>some script here</script>' +
|
||||||
|
'<style> h1 {color:red;} p {color:blue;}</style>',
|
||||||
|
updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)',
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
ampResult = ampContentHelper.call(testData);
|
||||||
|
|
||||||
|
ampResult.then(function (rendered) {
|
||||||
|
should.exist(rendered);
|
||||||
|
rendered.string.should.be.equal('');
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"node": "~0.10.0 || ~0.12.0 || ^4.2.0"
|
"node": "~0.10.0 || ~0.12.0 || ^4.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"amperize": "0.3.0",
|
"amperize": "https://github.com/aileencgn/amperize#fixed-layout-for-small-images",
|
||||||
"archiver": "1.0.1",
|
"archiver": "1.0.1",
|
||||||
"bcryptjs": "2.3.0",
|
"bcryptjs": "2.3.0",
|
||||||
"bluebird": "3.4.1",
|
"bluebird": "3.4.1",
|
||||||
|
|
Loading…
Add table
Reference in a new issue