mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 05:50:35 +03:00
Remove auto-inclusion of jQuery via ghost_foot
closes #5298 - remove all harcoded instances of jQuery throughout the front-end of the blog - add migration function to add cdn link to ghost_foot code injection when migrating up from version 003 - migration version bump
This commit is contained in:
parent
52e35a282b
commit
6c5fea40ca
47
Gruntfile.js
47
Gruntfile.js
@ -403,24 +403,10 @@ var _ = require('lodash'),
|
||||
// ### grunt-contrib-copy
|
||||
// Copy files into their correct locations as part of building assets, or creating release zips
|
||||
copy: {
|
||||
jquery: {
|
||||
cwd: 'core/client/bower_components/jquery/dist/',
|
||||
src: 'jquery.js',
|
||||
dest: 'core/built/public/',
|
||||
expand: true,
|
||||
nonull: true
|
||||
},
|
||||
release: {
|
||||
files: [{
|
||||
cwd: 'core/client/bower_components/jquery/dist/',
|
||||
src: 'jquery.js',
|
||||
dest: 'core/built/public/',
|
||||
expand: true
|
||||
}, {
|
||||
expand: true,
|
||||
src: buildGlob,
|
||||
dest: '<%= paths.releaseBuild %>/'
|
||||
}]
|
||||
expand: true,
|
||||
src: buildGlob,
|
||||
dest: '<%= paths.releaseBuild %>/'
|
||||
}
|
||||
},
|
||||
|
||||
@ -437,27 +423,6 @@ var _ = require('lodash'),
|
||||
}
|
||||
},
|
||||
|
||||
// ### grunt-contrib-uglify
|
||||
// Minify concatenated javascript files ready for production
|
||||
uglify: {
|
||||
prod: {
|
||||
options: {
|
||||
sourceMap: false
|
||||
},
|
||||
files: {
|
||||
'core/built/public/jquery.min.js': 'core/built/public/jquery.js'
|
||||
}
|
||||
},
|
||||
release: {
|
||||
options: {
|
||||
sourceMap: false
|
||||
},
|
||||
files: {
|
||||
'core/built/public/jquery.min.js': 'core/built/public/jquery.js'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// ### grunt-update-submodules
|
||||
// Grunt task to update git submodules
|
||||
update_submodules: {
|
||||
@ -920,7 +885,7 @@ var _ = require('lodash'),
|
||||
// ### Basic Asset Building
|
||||
// Builds and moves necessary client assets. Prod additionally builds the ember app.
|
||||
grunt.registerTask('assets', 'Basic asset building & moving',
|
||||
['clean:tmp', 'buildAboutPage', 'copy:jquery']);
|
||||
['clean:tmp', 'buildAboutPage']);
|
||||
|
||||
// ### Default asset build
|
||||
// `grunt` - default grunt task
|
||||
@ -934,7 +899,7 @@ var _ = require('lodash'),
|
||||
//
|
||||
// It is otherwise the same as running `grunt`, but is only used when running Ghost in the `production` env.
|
||||
grunt.registerTask('prod', 'Build JS & templates for production',
|
||||
['shell:ember:prod', 'uglify:prod', 'master-warn']);
|
||||
['shell:ember:prod', 'master-warn']);
|
||||
|
||||
// ### Live reload
|
||||
// `grunt dev` - build assets on the fly whilst developing
|
||||
@ -961,7 +926,7 @@ var _ = require('lodash'),
|
||||
' - Copy files to release-folder/#/#{version} directory\n' +
|
||||
' - Clean out unnecessary files (travis, .git*, etc)\n' +
|
||||
' - Zip files in release-folder to dist-folder/#{version} directory',
|
||||
['init', 'shell:ember:prod', 'uglify:release', 'clean:release', 'shell:shrinkwrap', 'copy:release', 'compress:release']);
|
||||
['init', 'shell:ember:prod', 'clean:release', 'shell:shrinkwrap', 'copy:release', 'compress:release']);
|
||||
};
|
||||
|
||||
module.exports = configureGrunt;
|
||||
|
@ -2,10 +2,11 @@
|
||||
// RESTful API for creating notifications
|
||||
var Promise = require('bluebird'),
|
||||
_ = require('lodash'),
|
||||
canThis = require('../permissions').canThis,
|
||||
permissions = require('../permissions'),
|
||||
errors = require('../errors'),
|
||||
utils = require('./utils'),
|
||||
pipeline = require('../utils/pipeline'),
|
||||
canThis = permissions.canThis,
|
||||
|
||||
// Holds the persistent notifications
|
||||
notificationsStore = [],
|
||||
@ -57,6 +58,10 @@ notifications = {
|
||||
* @returns {Object} options
|
||||
*/
|
||||
function handlePermissions(options) {
|
||||
if (permissions.parseContext(options.context).internal) {
|
||||
return Promise.resolve(options);
|
||||
}
|
||||
|
||||
return canThis(options.context).add.notification().then(function () {
|
||||
return options;
|
||||
}, function () {
|
||||
|
@ -9,14 +9,17 @@ var Promise = require('bluebird'),
|
||||
sequence = require('../../utils/sequence'),
|
||||
_ = require('lodash'),
|
||||
errors = require('../../errors'),
|
||||
config = require('../../config'),
|
||||
utils = require('../../utils'),
|
||||
models = require('../../models'),
|
||||
fixtures = require('./fixtures'),
|
||||
permissions = require('./permissions'),
|
||||
notifications = require('../../api/notifications'),
|
||||
|
||||
// Private
|
||||
logInfo,
|
||||
to003,
|
||||
to004,
|
||||
convertAdminToOwner,
|
||||
createOwner,
|
||||
options = {context: {internal: true}},
|
||||
@ -125,7 +128,7 @@ to003 = function () {
|
||||
Role = models.Role,
|
||||
Client = models.Client;
|
||||
|
||||
logInfo('Upgrading fixtures');
|
||||
logInfo('Upgrading fixtures to 003');
|
||||
|
||||
// Add the client fixture if missing
|
||||
upgradeOp = Client.findOne({secret: fixtures.clients[0].secret}).then(function (client) {
|
||||
@ -156,13 +159,61 @@ to003 = function () {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update ghost_foot to include a CDN of jquery if the DB is migrating from
|
||||
* @return {Promise}
|
||||
*/
|
||||
to004 = function () {
|
||||
var value,
|
||||
jquery = [
|
||||
'<!-- You can safely delete this line if your theme does not require jQuery -->\n',
|
||||
'<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>\n\n'
|
||||
],
|
||||
privacyMessage = [
|
||||
'jQuery has been removed from Ghost core and is now being loaded from the jQuery Foundation\'s CDN.',
|
||||
'This can be changed or removed in your <strong>Code Injection</strong> settings area.'
|
||||
];
|
||||
|
||||
logInfo('Upgrading fixtures to 004');
|
||||
|
||||
return models.Settings.findOne('ghost_foot').then(function (setting) {
|
||||
if (setting) {
|
||||
value = setting.attributes.value;
|
||||
// Only add jQuery if it's not already in there
|
||||
if (value.indexOf(jquery.join('')) === -1) {
|
||||
logInfo('Adding jQuery link to ghost_foot');
|
||||
value = jquery.join('') + value;
|
||||
return models.Settings.edit({key: 'ghost_foot', value: value}, options).then(function () {
|
||||
if (_.isEmpty(config.privacy)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
logInfo(privacyMessage.join(' ').replace(/<\/?strong>/g, ''));
|
||||
return notifications.add({notifications: [{
|
||||
type: 'info',
|
||||
message: privacyMessage.join(' ')
|
||||
}]}, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
update = function (fromVersion, toVersion) {
|
||||
var ops = [];
|
||||
|
||||
logInfo('Updating fixtures');
|
||||
// Are we migrating to, or past 003?
|
||||
if ((fromVersion < '003' && toVersion >= '003') ||
|
||||
fromVersion === '003' && toVersion === '003' && process.env.FORCE_MIGRATION) {
|
||||
return to003();
|
||||
ops.push(to003);
|
||||
}
|
||||
|
||||
if (fromVersion < '004' && toVersion === '004' ||
|
||||
fromVersion === '004' && toVersion === '004' && process.env.FORCE_MIGRATION) {
|
||||
ops.push(to004);
|
||||
}
|
||||
|
||||
return sequence(ops);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
@ -8,21 +8,13 @@
|
||||
|
||||
var hbs = require('express-hbs'),
|
||||
_ = require('lodash'),
|
||||
config = require('../config'),
|
||||
filters = require('../filters'),
|
||||
api = require('../api'),
|
||||
utils = require('./utils'),
|
||||
ghost_foot;
|
||||
|
||||
ghost_foot = function (options) {
|
||||
/*jshint unused:false*/
|
||||
var jquery = utils.isProduction ? 'jquery.min.js' : 'jquery.js',
|
||||
foot = [];
|
||||
|
||||
foot.push(utils.scriptTemplate({
|
||||
source: config.paths.subdir + '/public/' + jquery,
|
||||
version: config.assetHash
|
||||
}));
|
||||
var foot = [];
|
||||
|
||||
return api.settings.read({key: 'ghost_foot'}).then(function (response) {
|
||||
foot.push(response.settings[0].value);
|
||||
|
@ -128,7 +128,11 @@ describe('Tags API', function () {
|
||||
});
|
||||
|
||||
describe('Browse', function () {
|
||||
beforeEach(testUtils.setup('tags'));
|
||||
beforeEach(function (done) {
|
||||
testUtils.fixtures.insertMoreTags().then(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can browse (internal)', function (done) {
|
||||
TagAPI.browse(testUtils.context.internal).then(function (results) {
|
||||
|
40
core/test/integration/migration_spec.js
Normal file
40
core/test/integration/migration_spec.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
/*jshint expr:true*/
|
||||
var testUtils = require('../utils'),
|
||||
should = require('should'),
|
||||
|
||||
migration = require('../../server/data/migration/index'),
|
||||
Models = require('../../server/models');
|
||||
|
||||
describe('Database Migration (special functions)', function () {
|
||||
before(testUtils.teardown);
|
||||
afterEach(testUtils.teardown);
|
||||
|
||||
describe('004', function () {
|
||||
beforeEach(testUtils.setup('settings'));
|
||||
|
||||
it('should add jQuery to ghost_foot injection setting', function (done) {
|
||||
Models.Settings.findOne('ghost_foot').then(function (setting) {
|
||||
should.exist(setting);
|
||||
should.exist(setting.attributes);
|
||||
setting.attributes.value.should.equal('');
|
||||
|
||||
process.env.FORCE_MIGRATION = true; // force a migration
|
||||
migration.init().then(function () {
|
||||
Models.Settings.findOne('ghost_foot').then(function (result) {
|
||||
var jquery = [
|
||||
'<!-- You can safely delete this line if your theme does not require jQuery -->\n',
|
||||
'<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>\n\n'
|
||||
];
|
||||
|
||||
should.exist(result);
|
||||
should.exist(result.attributes);
|
||||
result.attributes.value.should.equal(jquery.join(''));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -19,85 +19,31 @@ describe('{{ghost_foot}} helper', function () {
|
||||
utils.loadHelpers();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
|
||||
it('has loaded ghost_foot helper', function () {
|
||||
should.exist(handlebars.helpers.ghost_foot);
|
||||
});
|
||||
|
||||
it('outputs correct injected code', function (done) {
|
||||
sandbox.stub(api.settings, 'read', function () {
|
||||
return Promise.resolve({
|
||||
settings: [{value: '<script type="text/javascript">var test = \'I am a variable!\'</script>'}]
|
||||
});
|
||||
});
|
||||
|
||||
helpers.ghost_foot.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.match(/<script type="text\/javascript">var test = 'I am a variable!'<\/script>/);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
utils.restoreConfig();
|
||||
helpers.__set__('utils.isProduction', false);
|
||||
});
|
||||
|
||||
describe('without Code Injection', function () {
|
||||
beforeEach(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
sandbox.stub(api.settings, 'read', function () {
|
||||
return Promise.resolve({
|
||||
settings: [{value: ''}]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('has loaded ghost_foot helper', function () {
|
||||
should.exist(handlebars.helpers.ghost_foot);
|
||||
});
|
||||
|
||||
it('outputs correct jquery for development mode', function (done) {
|
||||
utils.overrideConfig({assetHash: 'abc'});
|
||||
|
||||
helpers.ghost_foot.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.match(/<script src=".*\/public\/jquery.js\?v=abc"><\/script>/);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('outputs correct jquery for production mode', function (done) {
|
||||
utils.overrideConfig({assetHash: 'abc'});
|
||||
helpers.__set__('utils.isProduction', true);
|
||||
|
||||
helpers.ghost_foot.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.match(/<script src=".*\/public\/jquery.min.js\?v=abc"><\/script>/);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with Code Injection', function () {
|
||||
beforeEach(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
sandbox.stub(api.settings, 'read', function () {
|
||||
return Promise.resolve({
|
||||
settings: [{value: '<script></script>'}]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('outputs correct jquery for development mode', function (done) {
|
||||
utils.overrideConfig({assetHash: 'abc'});
|
||||
|
||||
helpers.ghost_foot.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.match(/<script src=".*\/public\/jquery.js\?v=abc"><\/script> <script><\/script>/);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('outputs correct jquery for production mode', function (done) {
|
||||
utils.overrideConfig({assetHash: 'abc'});
|
||||
helpers.__set__('utils.isProduction', true);
|
||||
|
||||
helpers.ghost_foot.call().then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.match(/<script src=".*\/public\/jquery.min.js\?v=abc"><\/script> <script><\/script>/);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -79,7 +79,6 @@
|
||||
"grunt-contrib-compress": "0.13.0",
|
||||
"grunt-contrib-copy": "0.8.0",
|
||||
"grunt-contrib-jshint": "0.11.2",
|
||||
"grunt-contrib-uglify": "0.9.1",
|
||||
"grunt-contrib-watch": "0.6.1",
|
||||
"grunt-docker": "0.0.10",
|
||||
"grunt-express-server": "0.5.1",
|
||||
|
Loading…
Reference in New Issue
Block a user