Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

adds extra_json field, wrapped in ACE

  • Loading branch information...
commit 3dc2fb3ddf4b85bdb481f4a10c6800fe29f2d1de 1 parent bbb1c04
@seanmonstar authored
View
8 apps/jetpack/templates/_edit_package_info.html
@@ -1,9 +1,9 @@
<form class="UI_Forms" id="package-info_form" method="post" accept-charset="utf-8">
- <h3>Edit {full_name} info</h3>
+ <h3>Edit #{full_name} info</h3>
<fieldset>
<label class="UI_Field">
<span>{{ revision.package.get_type_name_with_dash()|capfirst }} Name</span>
- <input type="text" name="full_name" id="full_name" class="validate-alphanum_plus_space" value="{full_name}"/>
+ <input type="text" name="full_name" id="full_name" class="validate-alphanum_plus_space" value="#{full_name}"/>
</label>
<label class="UI_Field">
<span>{{ revision.package.get_type_name_with_dash()|capfirst }} Description</span>
@@ -15,6 +15,10 @@
{% include "_package_privacy_toggle.html" %}
</ul>
</label>
+ <label class="UI_Field ace_editor_container">
+ <span>Extra package.json Properties</span>
+ <textarea id="package_extra_json" name="package_extra_json" rows="8" cols="40">{{revision.extra_json}}</textarea>
+ </label>
</fieldset>
<div class="UI_Modal_Actions">
<ul>
View
2  apps/jetpack/tests/test_views.py
@@ -279,7 +279,7 @@ def test_package_extra_json_change(self):
homepage = 'https://builder.addons.mozilla.org'
extra_json = '{ "homepage": "%s" }' % homepage
response = self.client.post(addon.latest.get_save_url(), {
- 'extra_json': extra_json})
+ 'package_extra_json': extra_json})
addon = Package.objects.get(pk=pk) # old one is cached
View
4 apps/jetpack/views.py
@@ -900,12 +900,12 @@ def save(request, id_number, type_id, revision_number=None,
revision.package.description = package_description
response_data['package_description'] = package_description
- extra_json = request.POST.get('extra_json')
+ extra_json = request.POST.get('package_extra_json')
if extra_json is not None:
# None means it wasn't submitted. We want to accept blank strings.
save_revision = True
revision.set_extra_json(extra_json, save=False)
- response_data['extra_json'] = extra_json
+ response_data['package_extra_json'] = extra_json
changes = []
View
26 media/jetpack/css/UI.Modal.css
@@ -287,3 +287,29 @@ authors:
width:69%;
padding:0 5px;
}
+
+.UI_Modal .UI_Field.ace_editor_container {
+ position:relative;
+}
+ .UI_Modal .UI_Field.ace_editor_container .ace_editor {
+ height:100px;
+ position:relative;
+ float:right;
+ width:260px;
+ }
+
+ .UI_Modal .UI_Field.ace_editor_container .ace_editor .ace_gutter {
+ width:15px;
+ }
+
+ .UI_Modal .UI_Field.ace_editor_container .validation-advice {
+ left:135px;
+ width:273px !important;
+ }
+
+ .UI_Modal .UI_Field.ace_editor_container textarea {
+ width:10px;
+ height:30px;
+ float:none;
+ padding:0;
+ }
View
61 media/jetpack/js/ide/controllers/PackageController.js
@@ -18,6 +18,7 @@ var Class = require('shipyard/class/Class'),
FloatingTips = require('../views/FloatingTips'),
Validator = require('../views/Validator'),
+ JSONValidator = require('../views/JSONValidator'),
//TODO: this is bad practice
settings = dom.window.get('settings');
@@ -48,7 +49,11 @@ module.exports = new Class({
save_el: 'package-save',
menu_el: 'UI_Editor_Menu',
- package_info_form_elements: ['full_name', 'package_description'],
+ package_info_form_elements: [
+ 'full_name',
+ 'package_description',
+ 'package_extra_json'
+ ],
check_dependencies: true,
check_if_latest: true // switch to false if displaying revisions
@@ -1328,7 +1333,8 @@ module.exports = new Class({
this.savenow = false;
var modal = fd().editPackageInfoModal = fd().displayModal(
string.substitute(settings.edit_package_info_template,
- object.merge({}, this.data, this.options)));
+ object.merge({}, this.data, this.options),
+ /#\{([^{}]+)\}/g));
modal.addListener('destroy', function() {
delete fd().editPackageInfoModal;
@@ -1339,6 +1345,8 @@ module.exports = new Class({
dom.$('package_description').addListener('change', function() {
fd().emit('change');
});
+
+
var savenow = dom.$('savenow');
if (savenow) {
savenow.addListener('click', function() {
@@ -1362,16 +1370,31 @@ module.exports = new Class({
pressedBtn.addClass('pressed').getElement('a').addClass('inactive');
notPressedBtn.removeClass('pressed').getElement('a').removeClass('inactive');
- var validator = new Validator('full_name', {
+ var fullNameValidator = new Validator('full_name', {
pattern: /^[A-Za-z0-9\s\-_\.\(\)]*$/,
message: 'Please use only letters, numbers, spaces, or "_().-" in this field.'
});
+ var jsonValidator = new JSONValidator('package_extra_json', {
+ message: 'Must be blank or a valid JSON object.'
+ });
+
+ var package_extra_json_el = dom.$('package_extra_json');
+ package_extra_json_el.store('json-validator', jsonValidator);
+ if ('package_extra_json' in this.options) {
+ package_extra_json_el.set('value', this.options.package_extra_json);
+ }
+
+ this._setupExtraPropertiesEditor();
+
+ function isValid() {
+ return fullNameValidator.validate() && jsonValidator.validate();
+ }
dom.$('package-info_form').addListener('submit', function(e) {
e.stop();
- if (validator.validate()) {
+ if (isValid()) {
controller.submitInfo();
} else {
- log.debug('Form field full_name field has invalid characters.');
+ log.debug('Invalid name or JSON.');
}
});
@@ -1384,6 +1407,34 @@ module.exports = new Class({
});
},
+ _setupExtraPropertiesEditor: function() {
+ // Make package.json textarea an ACE editor
+ var ace = require('ace/ace');
+
+ var extra_json_el = dom.$('package_extra_json');
+ extra_json_el.setStyle('display', 'none');
+ var extra_json_editor_el = new dom.Element('div', {
+ id: 'extra_json_ace',
+ text: extra_json_el.get('value')
+ });
+ extra_json_editor_el.inject(extra_json_el, 'before');
+ var editor = ace.edit(extra_json_editor_el.getNode());
+ var editorSession = editor.getSession();
+ editorSession.on('change', function() {
+ extra_json_el.set('value', editorSession.getValue());
+ fd().emit('change');
+ });
+
+ var validator = extra_json_el.retrieve('json-validator');
+ editor.on('blur', function() {
+ if (!validator.validate()) {
+ validator.show();
+ } else {
+ validator.hide();
+ }
+ });
+ },
+
/*
* Method: submitInfo
* submit info from EditInfoModalWindow
View
1  media/jetpack/js/ide/models/Package.js
@@ -31,6 +31,7 @@ var Package = module.exports = new Class({
revision_number: fields.NumberField(),
view_url: fields.TextField(),
active: fields.BooleanField(),
+ extra_json: fields.TextField(),
latest: fields.NumberField() // a FK to PackageRevision
View
23 media/jetpack/js/ide/views/JSONValidator.js
@@ -0,0 +1,23 @@
+var Class = require('shipyard/class/Class'),
+ typeOf = require('shipyard/utils/type').typeOf,
+ Validator = require('./Validator');
+
+module.exports = new Class({
+
+ Extends: Validator,
+
+ validate: function validate() {
+ var text = this.target.get('value').trim();
+ if (text) {
+ try {
+ var json = JSON.parse(text);
+ // number, string, array, etc are illegal.
+ return typeOf(json) === 'object';
+ } catch (jsonError) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+});
View
63 media/jetpack/js/ide/views/Validator.js
@@ -10,7 +10,12 @@ module.exports = new Class({
options: {
pattern: /.*/,
- message: 'Illegal characters found.'
+ messageTarget: null,
+ message: 'Illegal characters found.',
+ messageStyles: {
+ 'visibility': 'visible',
+ 'position': 'static'
+ }
},
initialize: function Validator(element, options) {
@@ -42,37 +47,39 @@ module.exports = new Class({
return this.options.pattern.test(value);
},
+ createElement: function() {
+ var messageTarget = dom.$(this.getOption('messageTarget')) || this.target;
+ this.element = new dom.Element('div', {
+ 'class': 'validation-advice',
+ 'text': this.getOption('message'),
+ 'styles': {
+ 'height': 0,
+ 'display': 'block',
+ 'overflow': 'hidden',
+ 'opacity': 0
+ }
+ });
+
+ //measure the height
+ this.element.setStyles({
+ 'visibility': 'hidden',
+ 'position': 'absolute'
+ });
+ this.element.inject(messageTarget, 'after');
+ this.height = this.element.getHeight();
+ this.element.dispose().setStyles(this.getOption('messageStyles'));
+
+ this.anim = new Anim(this.element, {
+ transition: Sine
+ });
+ },
+
show: function show() {
var validator = this;
if (!this.element) {
- this.element = new dom.Element('div', {
- 'class': 'validation-advice',
- 'text': this.getOption('message'),
- 'styles': {
- 'height': 0,
- 'display': 'block',
- 'overflow': 'hidden',
- 'opacity': 0
- }
- });
-
- //measure the height
- this.element.setStyles({
- 'visibility': 'hidden',
- 'position': 'absolute'
- });
- this.element.inject(validator.target, 'after');
- this.height = this.element.getHeight();
- this.element.dispose().setStyles({
- visibility: 'visible',
- position: 'static'
- });
-
- this.anim = new Anim(this.element, {
- transition: Sine
- });
- }
+ this.createElement();
+ }
this.anim.once('start', function() {
validator.element.inject(validator.target, 'after');
Please sign in to comment.
Something went wrong with that request. Please try again.