Upgrade Underscore.string

FEDX-117
This commit is contained in:
Andy Armstrong
2016-03-25 16:44:33 -04:00
committed by Brian Jacobel
parent f10a3c968e
commit db62db295c
21 changed files with 210 additions and 215 deletions

View File

@@ -51,7 +51,7 @@
"moment-with-locales": "js/vendor/moment-with-locales.min",
"text": 'js/vendor/requirejs/text',
"underscore": "common/js/vendor/underscore",
"underscore.string": "js/vendor/underscore.string.min",
"underscore.string": "common/js/vendor/underscore.string",
"backbone": "js/vendor/backbone-min",
"backbone-relational" : "js/vendor/backbone-relational.min",
"backbone.associations": "js/vendor/backbone-associations-min",

View File

@@ -27,7 +27,7 @@ requirejs.config({
"moment-with-locales": "xmodule_js/common_static/js/vendor/moment-with-locales.min",
"text": "xmodule_js/common_static/js/vendor/requirejs/text",
"underscore": "xmodule_js/common_static/common/js/vendor/underscore",
"underscore.string": "xmodule_js/common_static/js/vendor/underscore.string.min",
"underscore.string": "xmodule_js/common_static/common/js/vendor/underscore.string",
"backbone": "xmodule_js/common_static/js/vendor/backbone-min",
"backbone.associations": "xmodule_js/common_static/js/vendor/backbone-associations-min",
"backbone.paginator": "xmodule_js/common_static/js/vendor/backbone.paginator.min",

View File

@@ -23,7 +23,7 @@ requirejs.config({
"date": "xmodule_js/common_static/js/vendor/date",
"text": "xmodule_js/common_static/js/vendor/requirejs/text",
"underscore": "xmodule_js/common_static/common/js/vendor/underscore",
"underscore.string": "xmodule_js/common_static/js/vendor/underscore.string.min",
"underscore.string": "xmodule_js/common_static/common/js/vendor/underscore.string",
"backbone": "xmodule_js/common_static/js/vendor/backbone-min",
"backbone.associations": "xmodule_js/common_static/js/vendor/backbone-associations-min",
"backbone.paginator": "xmodule_js/common_static/js/vendor/backbone.paginator.min",

View File

@@ -104,11 +104,9 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
describe "EditTextbook", ->
describe "Basic", ->
tpl = readFixtures('edit-textbook.underscore')
chapterTpl = readFixtures('edit-chapter.underscore')
beforeEach ->
setFixtures($("<script>", {id: "edit-textbook-tpl", type: "text/template"}).text(tpl))
appendSetFixtures($("<script>", {id: "edit-chapter-tpl", type: "text/template"}).text(chapterTpl))
appendSetFixtures(sandbox({id: "page-notification"}))
appendSetFixtures(sandbox({id: "page-prompt"}))
@model = new Textbook({name: "Life Sciences", editing: true})
@@ -298,11 +296,8 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
describe "EditChapter", ->
tpl = readFixtures("edit-chapter.underscore")
beforeEach ->
modal_helpers.installModalTemplates()
appendSetFixtures($("<script>", {id: "edit-chapter-tpl", type: "text/template"}).text(tpl))
@model = new Chapter
name: "Chapter 1"
asset_path: "/ch1.pdf"

View File

@@ -1,100 +1,98 @@
// Backbone.js Application Model: Certificate
define([ // jshint ignore:line
'underscore',
'underscore.string',
'backbone',
'backbone-relational',
'backbone.associations',
'gettext',
'coffee/src/main',
'js/certificates/models/signatory',
'js/certificates/collections/signatories'
],
function (_, str, Backbone, BackboneRelational, BackboneAssociations, gettext, CoffeeSrcMain,
SignatoryModel, SignatoryCollection) {
'use strict';
_.str = str;
var Certificate = Backbone.RelationalModel.extend({
idAttribute: "id",
defaults: {
// Metadata fields currently displayed in web forms
course_title: '',
define([
'underscore',
'backbone',
'backbone-relational',
'backbone.associations',
'gettext',
'coffee/src/main',
'js/certificates/models/signatory',
'js/certificates/collections/signatories'
],
function(_, Backbone, BackboneRelational, BackboneAssociations, gettext, CoffeeSrcMain,
SignatoryModel, SignatoryCollection) {
'use strict';
var Certificate = Backbone.RelationalModel.extend({
idAttribute: 'id',
defaults: {
// Metadata fields currently displayed in web forms
course_title: '',
// Metadata fields not currently displayed in web forms
name: 'Name of the certificate',
description: 'Description of the certificate',
// Metadata fields not currently displayed in web forms
name: 'Name of the certificate',
description: 'Description of the certificate',
// Internal-use only, not displayed in web forms
version: 1,
is_active: false
},
// Internal-use only, not displayed in web forms
version: 1,
is_active: false
},
// Certificate child collection/model mappings (backbone-relational)
relations: [{
type: Backbone.HasMany,
key: 'signatories',
relatedModel: SignatoryModel,
collectionType: SignatoryCollection,
reverseRelation: {
key: 'certificate',
includeInJSON: "id"
// Certificate child collection/model mappings (backbone-relational)
relations: [{
type: Backbone.HasMany,
key: 'signatories',
relatedModel: SignatoryModel,
collectionType: SignatoryCollection,
reverseRelation: {
key: 'certificate',
includeInJSON: 'id'
}
}],
initialize: function(attributes, options) {
// Set up the initial state of the attributes set for this model instance
this.canBeEmpty = options && options.canBeEmpty;
if (options.add) {
// Ensure at least one child Signatory model is defined for any new Certificate model
attributes.signatories = new SignatoryModel({certificate: this});
}
this.setOriginalAttributes();
return this;
},
parse: function(response) {
// Parse must be defined for the model, but does not need to do anything special right now
return response;
},
setOriginalAttributes: function() {
// Remember the current state of this model (enables edit->cancel use cases)
this._originalAttributes = this.parse(this.toJSON());
this.get('signatories').each(function(modelSignatory) {
modelSignatory.setOriginalAttributes();
});
// If no url is defined for the signatories child collection we'll need to create that here as well
if (!this.isNew() && !this.get('signatories').url) {
this.get('signatories').url = this.collection.url + '/' + this.get('id') + '/signatories';
}
},
validate: function(attrs) {
// Ensure the provided attributes set meets our expectations for format, type, etc.
if (!attrs.name.trim()) {
return {
message: gettext('Certificate name is required.'),
attributes: {name: true}
};
}
var allSignatoriesValid = _.every(attrs.signatories.models, function(signatory){
return signatory.isValid();
});
if (!allSignatoriesValid) {
return {
message: gettext('Signatory field(s) has invalid data.'),
attributes: {signatories: attrs.signatories.models}
};
}
},
reset: function() {
// Revert the attributes of this model instance back to initial state
this.set(this._originalAttributes, {parse: true, validate: true});
}
}],
initialize: function(attributes, options) {
// Set up the initial state of the attributes set for this model instance
this.canBeEmpty = options && options.canBeEmpty;
if(options.add) {
// Ensure at least one child Signatory model is defined for any new Certificate model
attributes.signatories = new SignatoryModel({certificate: this});
}
this.setOriginalAttributes();
return this;
},
parse: function (response) {
// Parse must be defined for the model, but does not need to do anything special right now
return response;
},
setOriginalAttributes: function() {
// Remember the current state of this model (enables edit->cancel use cases)
this._originalAttributes = this.parse(this.toJSON());
this.get("signatories").each(function (modelSignatory) {
modelSignatory.setOriginalAttributes();
});
// If no url is defined for the signatories child collection we'll need to create that here as well
if(!this.isNew() && !this.get('signatories').url) {
this.get('signatories').url = this.collection.url + '/' + this.get('id') + '/signatories';
}
},
validate: function(attrs) {
// Ensure the provided attributes set meets our expectations for format, type, etc.
if (!_.str.trim(attrs.name)) {
return {
message: gettext('Certificate name is required.'),
attributes: {name: true}
};
}
var all_signatories_valid = _.every(attrs.signatories.models, function(signatory){
return signatory.isValid();
});
if (!all_signatories_valid) {
return {
message: gettext('Signatory field(s) has invalid data.'),
attributes: {signatories: attrs.signatories.models}
};
}
},
reset: function() {
// Revert the attributes of this model instance back to initial state
this.set(this._originalAttributes, { parse: true, validate: true });
}
});
return Certificate;
});
return Certificate;
});

View File

@@ -2,17 +2,15 @@
define([ // jshint ignore:line
'underscore',
'underscore.string',
'backbone',
'backbone-relational',
'gettext'
'underscore.string'
],
function(_, str, Backbone, BackboneRelational, gettext) {
function(_, Backbone) {
'use strict';
_.str = str;
var Signatory = Backbone.RelationalModel.extend({
idAttribute: "id",
idAttribute: 'id',
defaults: {
name: '',
title: '',
@@ -26,7 +24,7 @@ function(_, str, Backbone, BackboneRelational, gettext) {
return this;
},
parse: function (response) {
parse: function(response) {
// Parse must be defined for the model, but does not need to do anything special right now
return response;
},
@@ -38,7 +36,7 @@ function(_, str, Backbone, BackboneRelational, gettext) {
reset: function() {
// Revert the attributes of this model instance back to initial state
this.set(this._originalAttributes, { parse: true, validate: true });
this.set(this._originalAttributes, {parse: true, validate: true});
}
});
return Signatory;

View File

@@ -1,10 +1,9 @@
define([
'backbone', 'underscore', 'underscore.string', 'gettext', 'js/models/group',
'js/collections/group', 'backbone.associations', 'coffee/src/main'
'backbone', 'underscore', 'gettext', 'js/models/group', 'js/collections/group',
'backbone.associations', 'coffee/src/main'
],
function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
function(Backbone, _, gettext, GroupModel, GroupCollection) {
'use strict';
_.str = str;
var GroupConfiguration = Backbone.AssociatedModel.extend({
defaults: function() {
return {
@@ -49,7 +48,7 @@ function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
},
reset: function() {
this.set(this._originalAttributes, { parse: true, validate: true });
this.set(this._originalAttributes, {parse: true, validate: true});
},
isDirty: function() {
@@ -84,7 +83,7 @@ function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
},
validate: function(attrs) {
if (!_.str.trim(attrs.name)) {
if (!attrs.name.trim()) {
return {
message: gettext('Group Configuration name is required.'),
attributes: {name: true}
@@ -94,7 +93,7 @@ function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
if (!this.canBeEmpty && attrs.groups.length < 1) {
return {
message: gettext('There must be at least one group.'),
attributes: { groups: true }
attributes: {groups: true}
};
} else {
// validate all groups
@@ -111,7 +110,7 @@ function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
if (!invalidGroups.isEmpty()) {
return {
message: gettext('All groups must have a name.'),
attributes: { groups: invalidGroups.toJSON() }
attributes: {groups: invalidGroups.toJSON()}
};
}
@@ -119,13 +118,13 @@ function(Backbone, _, str, gettext, GroupModel, GroupCollection) {
if (groupNames.length !== _.uniq(groupNames).length) {
return {
message: gettext('All groups must have a unique name.'),
attributes: { groups: validGroups.toJSON() }
attributes: {groups: validGroups.toJSON()}
};
}
}
},
groupRemoved: function () {
groupRemoved: function() {
this.setOriginalAttributes();
}
});

View File

@@ -1,79 +1,84 @@
/*global course */
define(["js/views/baseview", "underscore", "underscore.string", "jquery", "gettext", "js/models/uploads", "js/views/uploads"],
function(BaseView, _, str, $, gettext, FileUploadModel, UploadDialogView) {
_.str = str; // used in template
var EditChapter = BaseView.extend({
initialize: function() {
this.template = this.loadTemplate('edit-chapter');
this.listenTo(this.model, "change", this.render);
},
tagName: "li",
className: function() {
return "field-group chapter chapter" + this.model.get('order');
},
render: function() {
this.$el.html(this.template({
name: this.model.get('name'),
asset_path: this.model.get('asset_path'),
order: this.model.get('order'),
error: this.model.validationError
}));
return this;
},
events: {
"change .chapter-name": "changeName",
"change .chapter-asset-path": "changeAssetPath",
"click .action-close": "removeChapter",
"click .action-upload": "openUploadDialog",
"submit": "uploadAsset"
},
changeName: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
name: this.$(".chapter-name").val()
}, {silent: true});
return this;
},
changeAssetPath: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
asset_path: this.$(".chapter-asset-path").val()
}, {silent: true});
return this;
},
removeChapter: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.collection.remove(this.model);
return this.remove();
},
openUploadDialog: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
name: this.$("input.chapter-name").val(),
asset_path: this.$("input.chapter-asset-path").val()
});
var msg = new FileUploadModel({
title: _.template(gettext("Upload a new PDF to “<%= name %>”"))(
{name: course.escape('name')}),
message: gettext("Please select a PDF file to upload."),
mimeTypes: ['application/pdf']
});
var that = this;
var view = new UploadDialogView({
model: msg,
onSuccess: function(response) {
var options = {};
if(!that.model.get('name')) {
options.name = response.asset.displayname;
}
options.asset_path = response.asset.portable_url;
that.model.set(options);
}
});
view.show();
}
});
define(['underscore', 'jquery', 'gettext', 'edx-ui-toolkit/js/utils/html-utils',
'js/views/baseview', 'js/models/uploads', 'js/views/uploads', 'text!templates/edit-chapter.underscore'],
function(_, $, gettext, HtmlUtils, BaseView, FileUploadModel, UploadDialogView, editChapterTemplate) {
'use strict';
return EditChapter;
});
var EditChapter = BaseView.extend({
initialize: function() {
this.template = HtmlUtils.template(editChapterTemplate);
this.listenTo(this.model, 'change', this.render);
},
tagName: 'li',
className: function() {
return 'field-group chapter chapter' + this.model.get('order');
},
render: function() {
HtmlUtils.setHtml(
this.$el,
this.template({
name: this.model.get('name'),
asset_path: this.model.get('asset_path'),
order: this.model.get('order'),
error: this.model.validationError
})
);
return this;
},
events: {
'change .chapter-name': 'changeName',
'change .chapter-asset-path': 'changeAssetPath',
'click .action-close': 'removeChapter',
'click .action-upload': 'openUploadDialog',
'submit': 'uploadAsset'
},
changeName: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
name: this.$('.chapter-name').val()
}, {silent: true});
return this;
},
changeAssetPath: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
asset_path: this.$('.chapter-asset-path').val()
}, {silent: true});
return this;
},
removeChapter: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.collection.remove(this.model);
return this.remove();
},
openUploadDialog: function(e) {
if(e && e.preventDefault) { e.preventDefault(); }
this.model.set({
name: this.$('input.chapter-name').val(),
asset_path: this.$('input.chapter-asset-path').val()
});
var msg = new FileUploadModel({
title: _.template(gettext('Upload a new PDF to “<%= name %>”'))(
{name: course.escape('name')}),
message: gettext('Please select a PDF file to upload.'),
mimeTypes: ['application/pdf']
});
var that = this;
var view = new UploadDialogView({
model: msg,
onSuccess: function(response) {
var options = {};
if (!that.model.get('name')) {
options.name = response.asset.displayname;
}
options.asset_path = response.asset.portable_url;
that.model.set(options);
}
});
view.show();
}
});
return EditChapter;
});

View File

@@ -3,11 +3,10 @@
* It is expected to be backed by a Group model.
*/
define([
'js/views/baseview', 'underscore', 'underscore.string', 'gettext'
'js/views/baseview'
],
function(BaseView, _, str, gettext) {
function(BaseView) {
'use strict';
_.str = str; // used in template
var ExperimentGroupEditView = BaseView.extend({
tagName: 'li',
events: {

View File

@@ -36,7 +36,7 @@ lib_paths:
- xmodule_js/common_static/js/vendor/jquery.cookie.js
- xmodule_js/common_static/js/vendor/jquery.simulate.js
- xmodule_js/common_static/common/js/vendor/underscore.js
- xmodule_js/common_static/js/vendor/underscore.string.min.js
- xmodule_js/common_static/common/js/vendor/underscore.string.js
- xmodule_js/common_static/js/vendor/backbone-min.js
- xmodule_js/common_static/js/vendor/backbone-associations-min.js
- xmodule_js/common_static/js/vendor/backbone.paginator.min.js

View File

@@ -35,7 +35,7 @@ lib_paths:
- xmodule_js/common_static/js/vendor/jquery-ui.min.js
- xmodule_js/common_static/js/vendor/jquery.cookie.js
- xmodule_js/common_static/common/js/vendor/underscore.js
- xmodule_js/common_static/js/vendor/underscore.string.min.js
- xmodule_js/common_static/common/js/vendor/underscore.string.js
- xmodule_js/common_static/js/vendor/backbone-min.js
- xmodule_js/common_static/js/vendor/backbone-associations-min.js
- xmodule_js/common_static/js/vendor/backbone.paginator.min.js

View File

@@ -10,7 +10,7 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json
<%block name="bodyclass">is-signedin course view-textbooks</%block>
<%block name="header_extras">
% for template_name in ["edit-textbook", "show-textbook", "edit-chapter", "no-textbooks", "basic-modal", "modal-button", "upload-dialog"]:
% for template_name in ["edit-textbook", "show-textbook", "no-textbooks", "basic-modal", "modal-button", "upload-dialog"]:
<script type="text/template" id="${template_name}-tpl">
<%static:include path="js/${template_name}.underscore" />
</script>

View File

@@ -23,7 +23,7 @@
'sinon': 'js/vendor/sinon-1.17.0',
'text': 'js/vendor/requirejs/text',
'underscore': 'common/js/vendor/underscore',
'underscore.string': 'js/vendor/underscore.string.min',
'underscore.string': 'common/js/vendor/underscore.string',
'backbone': 'js/vendor/backbone-min',
'backbone.associations': 'js/vendor/backbone-associations-min',
'backbone.paginator': 'js/vendor/backbone.paginator.min',

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,7 @@ lib_paths:
- js/vendor/jquery.truncate.js
- js/vendor/mustache.js
- common/js/vendor/underscore.js
- js/vendor/underscore.string.min.js
- common/js/vendor/underscore.string.js
- js/vendor/backbone-min.js
- js/vendor/jquery.timeago.js
- js/vendor/URI.min.js

View File

@@ -33,8 +33,8 @@ lib_paths:
- js/vendor/jasmine-imagediff.js
- js/vendor/jquery.simulate.js
- js/vendor/jquery.truncate.js
- js/vendor/underscore-min.js
- js/vendor/underscore.string.min.js
- common/js/vendor/underscore.js
- common/js/vendor/underscore.string.js
- js/vendor/backbone-min.js
- js/vendor/backbone.paginator.min.js
- js/vendor/jquery.timeago.js

View File

@@ -30,7 +30,7 @@
'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min',
'text': 'xmodule_js/common_static/js/vendor/requirejs/text',
'underscore': 'xmodule_js/common_static/common/js/vendor/underscore',
'underscore.string': 'xmodule_js/common_static/js/vendor/underscore.string.min',
'underscore.string': 'xmodule_js/common_static/common/js/vendor/underscore.string',
'backbone': 'xmodule_js/common_static/js/vendor/backbone-min',
'backbone.associations': 'xmodule_js/common_static/js/vendor/backbone-associations-min',
'backbone.paginator': 'xmodule_js/common_static/js/vendor/backbone.paginator.min',

View File

@@ -57,7 +57,7 @@ lib_paths:
- xmodule_js/src/xmodule.js
- xmodule_js/common_static/js/src/
- xmodule_js/common_static/common/js/vendor/underscore.js
- xmodule_js/common_static/js/vendor/underscore.string.min.js
- xmodule_js/common_static/common/js/vendor/underscore.string.js
- xmodule_js/common_static/js/vendor/backbone-min.js
- xmodule_js/common_static/js/vendor/backbone.paginator.min.js
- xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min.js

View File

@@ -29,11 +29,11 @@
};
defineDependency("jQuery", "jquery");
defineDependency("_", "underscore");
if (window._ && window._.str) {
define("underscore.string", [], function () {return window._.str;});
}
else {
console.error("Expected _.str (underscore.string) to be on the window object, but not found.");
defineDependency("s", "underscore.string");
// Underscore.string no longer installs itself directly on "_". For compatibility with existing
// code, add it to "_" with its previous name.
if (window._ && window.s) {
window._.str = window.s;
}
defineDependency("gettext", "gettext");
defineDependency("Logger", "logger");
@@ -62,7 +62,7 @@
"backbone-super": "js/vendor/backbone-super",
"backbone.paginator": "js/vendor/backbone.paginator.min",
"underscore": "common/js/vendor/underscore",
"underscore.string": "js/vendor/underscore.string.min",
"underscore.string": "common/js/vendor/underscore.string",
"jquery": "js/vendor/jquery.min",
"jquery.cookie": "js/vendor/jquery.cookie",
'jquery.timeago': 'js/vendor/jquery.timeago',

View File

@@ -7,7 +7,8 @@
"edx-ui-toolkit": "0.9.0",
"requirejs": "~2.1.22",
"uglify-js": "2.4.24",
"underscore": "~1.8.3"
"underscore": "~1.8.3",
"underscore.string": "~3.3.4"
},
"devDependencies": {
"jshint": "^2.7.0",

View File

@@ -39,7 +39,8 @@ COMMON_LOOKUP_DIRS = [
# A list of NPM installed libraries that should be copied into the common
# static directory.
NPM_INSTALLED_LIBRARIES = [
'underscore/underscore.js'
'underscore/underscore.js',
'underscore.string/dist/underscore.string.js'
]
# Directory to install static vendor files