* name: A string that is the binding name. It references a
(possibly nested) attribute of the associated viewlet's model.
+ * annotations: A hash on which viewlets can scribble whatever they
want
+ to.
* viewlet: (optional) The viewlet that is matched with this binding.
* target: (optional) Associated DOM node. If this exists, then it
is unique: no other binding in this engine shares it.
@@ -350,6 +352,9 @@
}
Reviewers: mp+185100_ code.launchpad. net,
Message:
Please take a look.
Description:
fix successive conflict UX calls
if you set a model value and then set a new one, the newest one will be
lost. This branch fixes that problem, and adds a test for simpler
conflict UX.
https:/ /code.launchpad .net/~gary/ juju-gui/ fixSuccessiveCo nflicts/ +merge/ 185100
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/13663043/
Affected files (+65, -26 lines): databinding. js inspector. js inspector_ constraints. js
A [revision details]
M app/views/
M app/views/
M test/test_
Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>
Index: test/test_ inspector_ constraints. js inspector_ constraints. js' inspector_ constraints. js 2013-09-11 00:22:45 +0000 inspector_ constraints. js 2013-09-11 15:40:06 +0000 isTrue( controls. hasClass( 'closed' ));
=== modified file 'test/test_
--- test/test_
+++ test/test_
@@ -247,4 +247,28 @@
assert.
});
+ it('handles conflicts correctly', function() { inspector) ; model.set( 'constraints' , {arch: 'lcars'}); container. one('input[ data-bind= "constraints. arch"]' ); 'click' ); '.settings- wrapper' ); one('.resolver .config-field'); equal(option. getHTML( ), 'lcars'); inspector) ; model.set( 'constraints' , {arch: 'lcars'}); model.set( 'constraints' , {arch: 'arm64'}); container. one('input[ data-bind= "constraints. arch"]' ); 'click' ); '.settings- wrapper' ); one('.resolver .config-field'); equal(option. getHTML( ), 'arm64');
+ var viewlet = getViewlet(
+ changeForm(viewlet, 'arch', 'i386');
+ inspector.
+ var node =
viewlet.
+ node.simulate(
+ var wrapper = node.ancestor(
+ var option = wrapper.
+ assert.
+ });
+
+ it('handles successive conflicts correctly', function() {
+ var viewlet = getViewlet(
+ changeForm(viewlet, 'arch', 'i386');
+ inspector.
+ // This is the successive change.
+ inspector.
+ var node =
viewlet.
+ node.simulate(
+ var wrapper = node.ancestor(
+ var option = wrapper.
+ assert.
+ });
+
});
Index: app/views/ databinding. js databinding. js' databinding. js 2013-09-11 14:22:16 +0000 databinding. js 2013-09-11 15:34:27 +0000
=== modified file 'app/views/
--- app/views/
+++ app/views/
@@ -300,6 +300,8 @@
* name: A string that is the binding name. It references a
nested) attribute of the associated viewlet's model.
unique: no other binding in this engine shares it.
(possibly
+ * annotations: A hash on which viewlets can scribble whatever they
want
+ to.
* viewlet: (optional) The viewlet that is matched with this binding.
* target: (optional) Associated DOM node. If this exists, then it
is
@@ -350,6 +352,9 @@
}
+ if (binding.
+ binding.annotations = {};
+ }
return binding;
};
Index: app/views/ inspector. js inspector. js' inspector. js 2013-09-11 03:13:28 +0000 inspector. js 2013-09-11 15:44:24 +0000 'bind') ; one('.config- field') ;
=== modified file 'app/views/
--- app/views/
+++ app/views/
@@ -1204,6 +1204,7 @@
Calls the databinding resolve method
@method sendResolve
*/
+ var viewlet = this;
var key = node.getData(
var modelValue = model.get(key);
var field = binding.field;
@@ -1212,41 +1213,51 @@
var option = resolver.
var handlers = [];
+ if (binding. annotations. conflict) { annotations. conflict. cancel( ); annotations. conflict = { forEach( function( h) { h.detach();}); _clearModified( node); _clearConflictP ending( node); _clearConflict( node); addClass( 'hidden' ); annotations. conflict;
e.halt( true); forEach( function( h) { h.detach();}); fied(node) ; lict(node) ; addClass( 'hidden' ); annotations. conflict. cancel( ); t.hasClass( 'conflicted- env')) {
resolve( modelValue) ;
resolve( formValue) ;
+ binding.
+ }
+
+ binding.
+ /**
+ Cancel this conflict handling UX.
+
+ @method cancel
+ */
+ cancel: function() {
+ handlers.
+ viewlet.
+ viewlet.
+ viewlet.
+ resolver.
+ delete binding.
+ }
+ };
/**
- User selects one of the two conflicting values.
- @method sendResolve
+ User selects one of the two conflicting values.
+
+ @method sendResolve
*/
function sendResolve(e) {
- var formValue = field.get(node);
- handlers.
-
- /* jshint -W040 */
- // Ignore 'possible strict violation'
- this._clearModi
- this._clearConf
-
- resolver.
-
+ binding.
if (e.currentTarge
} else {
+ var formValue = field.get(node);
}
}
/**
- User selects a conflicting field, show the resolution UI
+ User selects a conflicting field, show the resolution UI
- @method setupResolver
e.halt( true); lictPending( node); ict(node) ; ict(option) ; _clearConflictP ending( node); _makeConflict( node); _makeConflict( option) ;
option. setStyle( 'width' , node.get( 'offsetWidth' ));
option. setHTML( modelValue) ;
resolver. removeClass( 'hidden' );
this._ makeConflictPen ding(node) ;
+ @method setupResolver
*/
function setupResolver(e) {
- /* jshint -W040 */
- // Ignore 'possible strict violation'
- this._clearConf
- this._makeConfl
- this._makeConfl
+ viewlet.
+ viewlet.
+ viewlet.
@@ -1257,14 +1268,10 @@
- 'click',
- setupResolver,
- '.conflict-
- this));
+ 'click', setupResolver, '.conflict-
+ handlers.
+ },
- handlers. push(wrapper. delegate( 'click' , sendResolve, unsyncedFields' : function() { one('.controls .confirm'); getData( 'originalText' )) {
node.setHTML( 'Overwrite' ); syncedFields' : function() { one('.controls' ); one('.confirm' );
- '.conflict', this));
- },
'
var node = this.container.
if (!node.
@@ -1272,6 +1279,7 @@
}
},
+
'
var controls = this.container.
var node = controls.