Merge changes Ie54178b7,I6fda4cce,I2f82060e,I9f95d6fc,I1bbdda5a
* changes: Add Gerrit.getLoggedIn to JS API Add change view reply dialog JS interface Add change view actions JS interface Add experimental labelchange event in JS API Add optional version parameter to JS API
This commit is contained in:
@@ -59,7 +59,7 @@ limitations under the License.
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<section hidden$="[[!_keyCount(actions)]]" hidden>
|
||||
<section hidden$="[[!_actionCount(actions.*, _additionalActions.*)]]">
|
||||
<div class="groupLabel">Change</div>
|
||||
<template is="dom-repeat" items="[[_changeActionValues]]" as="action">
|
||||
<gr-button title$="[[action.title]]"
|
||||
@@ -72,7 +72,7 @@ limitations under the License.
|
||||
on-tap="_handleActionTap"></gr-button>
|
||||
</template>
|
||||
</section>
|
||||
<section hidden$="[[!_keyCount(_revisionActions)]]" hidden>
|
||||
<section hidden$="[[!_actionCount(_revisionActions.*, _additionalActions.*)]]">
|
||||
<div class="groupLabel">Revision</div>
|
||||
<template is="dom-repeat" items="[[_revisionActionValues]]" as="action">
|
||||
<gr-button title$="[[action.title]]"
|
||||
|
||||
@@ -59,7 +59,10 @@
|
||||
*/
|
||||
|
||||
properties: {
|
||||
actions: Object,
|
||||
actions: {
|
||||
type: Object,
|
||||
value: function() { return {}; },
|
||||
},
|
||||
primaryActionKeys: {
|
||||
type: Array,
|
||||
value: function() {
|
||||
@@ -77,7 +80,10 @@
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
_revisionActions: Object,
|
||||
_revisionActions: {
|
||||
type: Object,
|
||||
value: function() { return {}; },
|
||||
},
|
||||
_revisionActionValues: {
|
||||
type: Array,
|
||||
computed: '_computeRevisionActionValues(_revisionActions.*, ' +
|
||||
@@ -103,7 +109,7 @@
|
||||
],
|
||||
|
||||
observers: [
|
||||
'_actionsChanged(actions, _revisionActions, _additionalActions)',
|
||||
'_actionsChanged(actions.*, _revisionActions.*, _additionalActions.*)',
|
||||
],
|
||||
|
||||
ready: function() {
|
||||
@@ -129,7 +135,7 @@
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
addActionButton: function(key, type, label) {
|
||||
addActionButton: function(type, label) {
|
||||
if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
|
||||
throw Error('Invalid action type: ' + type);
|
||||
}
|
||||
@@ -137,39 +143,59 @@
|
||||
enabled: true,
|
||||
label: label,
|
||||
__type: type,
|
||||
__key: ADDITIONAL_ACTION_KEY_PREFIX + key + Math.random().toString(36),
|
||||
__key: ADDITIONAL_ACTION_KEY_PREFIX + Math.random().toString(36),
|
||||
};
|
||||
this.push('_additionalActions', action);
|
||||
return action.__key;
|
||||
},
|
||||
|
||||
removeActionButton: function(key) {
|
||||
var idx = -1;
|
||||
for (var i = 0; i < this._additionalActions.length; i++) {
|
||||
if (this._additionalActions[i].__key === key) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var idx = this._indexOfActionButtonWithKey(key);
|
||||
if (idx === -1) {
|
||||
console.error('Could not find action button with key:', key);
|
||||
return;
|
||||
}
|
||||
this.splice('_additionalActions', idx, 1);
|
||||
},
|
||||
|
||||
setActionButtonProp: function(key, prop, value) {
|
||||
this.set([
|
||||
'_additionalActions',
|
||||
this._indexOfActionButtonWithKey(key),
|
||||
prop,
|
||||
], value);
|
||||
},
|
||||
|
||||
_indexOfActionButtonWithKey: function(key) {
|
||||
for (var i = 0; i < this._additionalActions.length; i++) {
|
||||
if (this._additionalActions[i].__key === key) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
_getRevisionActions: function() {
|
||||
return this.$.restAPI.getChangeRevisionActions(this.changeNum,
|
||||
this.patchNum);
|
||||
},
|
||||
|
||||
_keyCount: function(obj) {
|
||||
return Object.keys(obj).length;
|
||||
_actionCount: function(actionsChangeRecord, additionalActionsChangeRecord) {
|
||||
var additionalActions = (additionalActionsChangeRecord &&
|
||||
additionalActionsChangeRecord.base) || [];
|
||||
return this._keyCount(actionsChangeRecord) + additionalActions.length;
|
||||
},
|
||||
|
||||
_actionsChanged: function(actions, revisionActions, additionalActions) {
|
||||
this.hidden = this._keyCount(actions) === 0 &&
|
||||
this._keyCount(revisionActions) === 0 &&
|
||||
this._keyCount(additionalActions) === 0;
|
||||
_keyCount: function(changeRecord) {
|
||||
return Object.keys((changeRecord && changeRecord.base) || {}).length;
|
||||
},
|
||||
|
||||
_actionsChanged: function(actionsChangeRecord, revisionActionsChangeRecord,
|
||||
additionalActionsChangeRecord) {
|
||||
var additionalActions = (additionalActionsChangeRecord &&
|
||||
additionalActionsChangeRecord.base) || [];
|
||||
this.hidden = this._keyCount(actionsChangeRecord) === 0 &&
|
||||
this._keyCount(revisionActionsChangeRecord) === 0 &&
|
||||
additionalActions.length === 0;
|
||||
},
|
||||
|
||||
_getValuesFor: function(obj) {
|
||||
|
||||
@@ -203,8 +203,7 @@ limitations under the License.
|
||||
test('custom actions', function(done) {
|
||||
// Add a button with the same key as a server-based one to ensure
|
||||
// collisions are taken care of.
|
||||
var key = element.addActionButton('submit', element.ActionType.REVISION,
|
||||
'Bork!');
|
||||
var key = element.addActionButton(element.ActionType.REVISION, 'Bork!');
|
||||
element.addEventListener(key + '-tap', function(e) {
|
||||
assert.equal(e.detail.node.getAttribute('data-action-key'), key);
|
||||
element.removeActionButton(key);
|
||||
|
||||
@@ -93,6 +93,10 @@
|
||||
Gerrit.RESTClientBehavior,
|
||||
],
|
||||
|
||||
observers: [
|
||||
'_labelsChanged(_change.labels.*)',
|
||||
],
|
||||
|
||||
ready: function() {
|
||||
this._headerEl = this.$$('.header');
|
||||
},
|
||||
@@ -485,6 +489,13 @@
|
||||
}
|
||||
},
|
||||
|
||||
_labelsChanged: function(changeRecord) {
|
||||
if (!changeRecord) { return; }
|
||||
this.$.jsAPI.handleEvent(this.$.jsAPI.EventType.LABEL_CHANGE, {
|
||||
change: this._change,
|
||||
});
|
||||
},
|
||||
|
||||
_openReplyDialog: function() {
|
||||
this.$.replyOverlay.open().then(function() {
|
||||
this.$.replyOverlay.setFocusStops(this.$.replyDialog.getFocusStops());
|
||||
|
||||
@@ -19,6 +19,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../../bower_components/iron-selector/iron-selector.html">
|
||||
<link rel="import" href="../../../behaviors/rest-client-behavior.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<dom-module id="gr-reply-dialog">
|
||||
@@ -154,6 +155,7 @@ limitations under the License.
|
||||
on-tap="_cancelTapHandler">Cancel</gr-button>
|
||||
</section>
|
||||
</div>
|
||||
<gr-js-api-interface id="jsAPI"></gr-js-api-interface>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-reply-dialog.js"></script>
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
ready: function() {
|
||||
this.$.jsAPI.addElement(this.$.jsAPI.Element.REPLY_DIALOG, this);
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
this.async(function() {
|
||||
this.$.textarea.textarea.focus();
|
||||
@@ -72,6 +76,48 @@
|
||||
};
|
||||
},
|
||||
|
||||
setLabelValue: function(label, value) {
|
||||
var selectorEl = this.$$('iron-selector[data-label="' + label + '"]');
|
||||
// The selector may not be present if it’s not at the latest patch set.
|
||||
if (!selectorEl) { return; }
|
||||
var item = selectorEl.$$('gr-button[data-value="' + value + '"]');
|
||||
if (!item) { return; }
|
||||
selectorEl.selectIndex(selectorEl.indexOf(item));
|
||||
},
|
||||
|
||||
send: function() {
|
||||
var obj = {
|
||||
drafts: 'PUBLISH_ALL_REVISIONS',
|
||||
labels: {},
|
||||
};
|
||||
for (var label in this.permittedLabels) {
|
||||
if (!this.permittedLabels.hasOwnProperty(label)) { continue; }
|
||||
|
||||
var selectorEl = this.$$('iron-selector[data-label="' + label + '"]');
|
||||
|
||||
// The selector may not be present if it’s not at the latest patch set.
|
||||
if (!selectorEl) { continue; }
|
||||
|
||||
var selectedVal = selectorEl.selectedItem.getAttribute('data-value');
|
||||
selectedVal = parseInt(selectedVal, 10);
|
||||
obj.labels[label] = selectedVal;
|
||||
}
|
||||
if (this.draft != null) {
|
||||
obj.message = this.draft;
|
||||
}
|
||||
this.disabled = true;
|
||||
return this._saveReview(obj).then(function(response) {
|
||||
this.disabled = false;
|
||||
if (!response.ok) { return response; }
|
||||
|
||||
this.draft = '';
|
||||
this.fire('send', null, {bubbles: false});
|
||||
}.bind(this)).catch(function(err) {
|
||||
this.disabled = false;
|
||||
throw err;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_computeShowLabels: function(patchNum, revisions) {
|
||||
var num = parseInt(patchNum, 10);
|
||||
for (var rev in revisions) {
|
||||
@@ -147,34 +193,7 @@
|
||||
|
||||
_sendTapHandler: function(e) {
|
||||
e.preventDefault();
|
||||
var obj = {
|
||||
drafts: 'PUBLISH_ALL_REVISIONS',
|
||||
labels: {},
|
||||
};
|
||||
for (var label in this.permittedLabels) {
|
||||
var selectorEl = this.$$('iron-selector[data-label="' + label + '"]');
|
||||
|
||||
// The selector may not be present if it’s not at the latest patch set.
|
||||
if (!selectorEl) { continue; }
|
||||
|
||||
var selectedVal = selectorEl.selectedItem.getAttribute('data-value');
|
||||
selectedVal = parseInt(selectedVal, 10);
|
||||
obj.labels[label] = selectedVal;
|
||||
}
|
||||
if (this.draft != null) {
|
||||
obj.message = this.draft;
|
||||
}
|
||||
this.disabled = true;
|
||||
this._saveReview(obj).then(function(response) {
|
||||
this.disabled = false;
|
||||
if (!response.ok) { return response; }
|
||||
|
||||
this.draft = '';
|
||||
this.fire('send', null, {bubbles: false});
|
||||
}.bind(this)).catch(function(err) {
|
||||
this.disabled = false;
|
||||
throw err;
|
||||
}.bind(this));
|
||||
this.send();
|
||||
},
|
||||
|
||||
_saveReview: function(review) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2016 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
function GrChangeActionsInterface(el) {
|
||||
this._el = el;
|
||||
this.RevisionActions = el.RevisionActions;
|
||||
this.ChangeActions = el.ChangeActions;
|
||||
this.ActionType = el.ActionType;
|
||||
}
|
||||
|
||||
GrChangeActionsInterface.prototype.addPrimaryActionKey = function(key) {
|
||||
if (this._el.primaryActionKeys.indexOf(key) !== -1) { return; }
|
||||
|
||||
this._el.push('primaryActionKeys', key);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.removePrimaryActionKey = function(key) {
|
||||
this._el.primaryActionKeys = this._el.primaryActionKeys.filter(function(k) {
|
||||
return k !== key;
|
||||
});
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.add = function(type, label) {
|
||||
return this._el.addActionButton(type, label);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.remove = function(key) {
|
||||
return this._el.removeActionButton(key);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.addTapListener = function(key, handler) {
|
||||
this._el.addEventListener(key + '-tap', handler);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.removeTapListener = function(key,
|
||||
handler) {
|
||||
this._el.removeEventListener(key + '-tap', handler);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.setLabel = function(key, text) {
|
||||
this._el.setActionButtonProp(key, 'label', text);
|
||||
};
|
||||
|
||||
GrChangeActionsInterface.prototype.setEnabled = function(key, enabled) {
|
||||
this._el.setActionButtonProp(key, 'enabled', enabled);
|
||||
};
|
||||
|
||||
window.GrChangeActionsInterface = GrChangeActionsInterface;
|
||||
})(window);
|
||||
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-change-actions-js-api</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||
<!--
|
||||
This must refer to the element this interface is wrapping around. Otherwise
|
||||
breaking changes to gr-change-actions won’t be noticed.
|
||||
-->
|
||||
<link rel="import" href="../../change/gr-change-actions/gr-change-actions.html">
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-change-actions></gr-change-actions>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-js-api-interface tests', function() {
|
||||
var element;
|
||||
var changeActions;
|
||||
|
||||
setup(function() {
|
||||
element = fixture('basic');
|
||||
var plugin;
|
||||
Gerrit.install(function(p) { plugin = p; }, '0.1',
|
||||
'http://test.com/plugins/testplugin/static/test.js');
|
||||
changeActions = plugin.changeActions();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
changeActions = null;
|
||||
});
|
||||
|
||||
test('property existence', function() {
|
||||
[
|
||||
'ActionType',
|
||||
'ChangeActions',
|
||||
'RevisionActions',
|
||||
].forEach(function(p) {
|
||||
assertArraysEqual(changeActions[p], element[p]);
|
||||
});
|
||||
});
|
||||
|
||||
// Because deepEqual doesn’t behave in Safari.
|
||||
function assertArraysEqual(actual, expected) {
|
||||
assert.equal(actual.length, expected.length);
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
assert.equal(actual[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
test('add/remove primary action keys', function() {
|
||||
element.primaryActionKeys = [];
|
||||
changeActions.addPrimaryActionKey('foo');
|
||||
assertArraysEqual(element.primaryActionKeys, ['foo']);
|
||||
changeActions.addPrimaryActionKey('foo');
|
||||
assertArraysEqual(element.primaryActionKeys, ['foo']);
|
||||
changeActions.addPrimaryActionKey('bar');
|
||||
assertArraysEqual(element.primaryActionKeys, ['foo', 'bar']);
|
||||
changeActions.removePrimaryActionKey('foo');
|
||||
assertArraysEqual(element.primaryActionKeys, ['bar']);
|
||||
changeActions.removePrimaryActionKey('baz');
|
||||
assertArraysEqual(element.primaryActionKeys, ['bar']);
|
||||
changeActions.removePrimaryActionKey('bar');
|
||||
assertArraysEqual(element.primaryActionKeys, []);
|
||||
});
|
||||
|
||||
test('action buttons', function(done) {
|
||||
var key = changeActions.add(changeActions.ActionType.REVISION, 'Bork!');
|
||||
var handler = sinon.spy();
|
||||
changeActions.addTapListener(key, handler);
|
||||
flush(function() {
|
||||
MockInteractions.tap(element.$$('[data-action-key="' + key + '"]'));
|
||||
assert(handler.calledOnce);
|
||||
changeActions.removeTapListener(key, handler);
|
||||
MockInteractions.tap(element.$$('[data-action-key="' + key + '"]'));
|
||||
assert(handler.calledOnce);
|
||||
changeActions.remove(key);
|
||||
flush(function() {
|
||||
assert.isNull(element.$$('[data-action-key="' + key + '"]'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('action button properties', function(done) {
|
||||
var key = changeActions.add(changeActions.ActionType.REVISION, 'Bork!');
|
||||
flush(function() {
|
||||
var button = element.$$('[data-action-key="' + key + '"]');
|
||||
assert.isOk(button);
|
||||
assert.equal(button.getAttribute('data-label'), 'Bork!');
|
||||
assert.isFalse(button.disabled);
|
||||
changeActions.setLabel(key, 'Yo');
|
||||
changeActions.setEnabled(key, false);
|
||||
flush(function() {
|
||||
assert.equal(button.getAttribute('data-label'), 'Yo');
|
||||
assert.isTrue(button.disabled);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2016 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
function GrChangeReplyInterface(el) {
|
||||
this._el = el;
|
||||
}
|
||||
|
||||
GrChangeReplyInterface.prototype.setLabelValue = function(label, value) {
|
||||
this._el.setLabelValue(label, value);
|
||||
};
|
||||
|
||||
GrChangeReplyInterface.prototype.send = function() {
|
||||
return this._el.send();
|
||||
};
|
||||
|
||||
window.GrChangeReplyInterface = GrChangeReplyInterface;
|
||||
})(window);
|
||||
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-change-reply-js-api</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||
<!--
|
||||
This must refer to the element this interface is wrapping around. Otherwise
|
||||
breaking changes to gr-reply-dialog won’t be noticed.
|
||||
-->
|
||||
<link rel="import" href="../../change/gr-reply-dialog/gr-reply-dialog.html">
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-reply-dialog></gr-reply-dialog>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-change-reply-js-api tests', function() {
|
||||
var element;
|
||||
var sandbox;
|
||||
var changeReply;
|
||||
|
||||
setup(function() {
|
||||
stub('gr-rest-api-interface', {
|
||||
getAccount: function() { return Promise.resolve(null); },
|
||||
});
|
||||
element = fixture('basic');
|
||||
sandbox = sinon.sandbox.create();
|
||||
var plugin;
|
||||
Gerrit.install(function(p) { plugin = p; }, '0.1',
|
||||
'http://test.com/plugins/testplugin/static/test.js');
|
||||
changeReply = plugin.changeReply();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
changeReply = null;
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('calls', function() {
|
||||
var setLabelValueStub = sinon.stub(element, 'setLabelValue');
|
||||
changeReply.setLabelValue('My-Label', '+1337');
|
||||
assert(setLabelValueStub.calledWithExactly('My-Label', '+1337'));
|
||||
|
||||
var sendStub = sinon.stub(element, 'send');
|
||||
changeReply.send();
|
||||
assert(sendStub.calledWithExactly());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -14,9 +14,12 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<dom-module id="gr-js-api-interface">
|
||||
<template></template>
|
||||
<script src="gr-change-actions-js-api.js"></script>
|
||||
<script src="gr-change-reply-js-api.js"></script>
|
||||
<script src="gr-js-api-interface.js"></script>
|
||||
<script src="gr-public-js-api.js"></script>
|
||||
</dom-module>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
var EventType = {
|
||||
HISTORY: 'history',
|
||||
LABEL_CHANGE: 'labelchange',
|
||||
SHOW_CHANGE: 'showchange',
|
||||
SUBMIT_CHANGE: 'submitchange',
|
||||
COMMENT: 'comment',
|
||||
@@ -23,6 +24,7 @@
|
||||
|
||||
var Element = {
|
||||
CHANGE_ACTIONS: 'changeactions',
|
||||
REPLY_DIALOG: 'replydialog',
|
||||
};
|
||||
|
||||
Polymer({
|
||||
@@ -53,6 +55,9 @@
|
||||
case EventType.COMMENT:
|
||||
this._handleComment(detail);
|
||||
break;
|
||||
case EventType.LABEL_CHANGE:
|
||||
this._handleLabelChange(detail);
|
||||
break;
|
||||
default:
|
||||
console.warn('handleEvent called with unsupported event type:', type);
|
||||
break;
|
||||
@@ -133,6 +138,16 @@
|
||||
});
|
||||
},
|
||||
|
||||
_handleLabelChange: function(detail) {
|
||||
this._getEventCallbacks(EventType.LABEL_CHANGE).forEach(function(cb) {
|
||||
try {
|
||||
cb(detail.change);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_getEventCallbacks: function(type) {
|
||||
return this._eventCallbacks[type] || [];
|
||||
},
|
||||
|
||||
@@ -38,9 +38,14 @@ limitations under the License.
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
stub('gr-rest-api-interface', {
|
||||
getAccount: function() {
|
||||
return Promise.resolve({name: 'Judy Hopps'});
|
||||
},
|
||||
})
|
||||
element = fixture('basic');
|
||||
errorStub = sinon.stub(console, 'error');
|
||||
Gerrit.install(function(p) { plugin = p; },
|
||||
Gerrit.install(function(p) { plugin = p; }, '0.1',
|
||||
'http://test.com/plugins/testplugin/static/test.js');
|
||||
});
|
||||
|
||||
@@ -97,6 +102,17 @@ limitations under the License.
|
||||
element.handleEvent(element.EventType.COMMENT, {node: testCommentNode});
|
||||
});
|
||||
|
||||
test('labelchange event', function(done) {
|
||||
var testChange = {_number: 42};
|
||||
plugin.on(element.EventType.LABEL_CHANGE, throwErrFn);
|
||||
plugin.on(element.EventType.LABEL_CHANGE, function(change) {
|
||||
assert.deepEqual(change, testChange);
|
||||
assert.isTrue(errorStub.calledOnce);
|
||||
done();
|
||||
});
|
||||
element.handleEvent(element.EventType.LABEL_CHANGE, {change: testChange});
|
||||
});
|
||||
|
||||
test('submitchange', function() {
|
||||
plugin.on(element.EventType.SUBMIT_CHANGE, throwErrFn);
|
||||
plugin.on(element.EventType.SUBMIT_CHANGE, function() { return true; });
|
||||
@@ -108,5 +124,18 @@ limitations under the License.
|
||||
assert.isTrue(errorStub.calledTwice);
|
||||
});
|
||||
|
||||
test('versioning', function() {
|
||||
var callback = sinon.spy();
|
||||
Gerrit.install(callback, '0.0pre-alpha');
|
||||
assert(callback.notCalled);
|
||||
});
|
||||
|
||||
test('getAccount', function(done) {
|
||||
Gerrit.getLoggedIn().then(function(loggedIn) {
|
||||
assert.isTrue(loggedIn);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -14,11 +14,19 @@
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
var API_VERSION = '0.1';
|
||||
|
||||
// GWT JSNI uses $wnd to refer to window.
|
||||
// http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html
|
||||
window.$wnd = window;
|
||||
|
||||
function Plugin(opt_url) {
|
||||
if (!opt_url) {
|
||||
console.warn('Plugin not being loaded from /plugins base path.',
|
||||
'Unable to determine name.');
|
||||
return;
|
||||
}
|
||||
|
||||
this._url = new URL(opt_url);
|
||||
if (this._url.pathname.indexOf('/plugins') !== 0) {
|
||||
console.warn('Plugin not being loaded from /plugins base path:',
|
||||
@@ -44,9 +52,14 @@
|
||||
return this._url.origin + '/plugins/' + this._name + (opt_path || '/');
|
||||
};
|
||||
|
||||
Plugin.prototype.getChangeActionsElement = function() {
|
||||
return Plugin._sharedAPIElement.getElement(
|
||||
Plugin._sharedAPIElement.Element.CHANGE_ACTIONS);
|
||||
Plugin.prototype.changeActions = function() {
|
||||
return new GrChangeActionsInterface(Plugin._sharedAPIElement.getElement(
|
||||
Plugin._sharedAPIElement.Element.CHANGE_ACTIONS));
|
||||
};
|
||||
|
||||
Plugin.prototype.changeReply = function() {
|
||||
return new GrChangeReplyInterface(Plugin._sharedAPIElement.getElement(
|
||||
Plugin._sharedAPIElement.Element.REPLY_DIALOG));
|
||||
};
|
||||
|
||||
var Gerrit = window.Gerrit || {};
|
||||
@@ -68,12 +81,22 @@
|
||||
return name;
|
||||
};
|
||||
|
||||
Gerrit.install = function(callback, opt_src) {
|
||||
Gerrit.install = function(callback, opt_version, opt_src) {
|
||||
if (opt_version && opt_version !== API_VERSION) {
|
||||
console.warn('Only version ' + API_VERSION +
|
||||
' is supported in PolyGerrit. ' + opt_version + ' was given.');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(andybons): Polyfill currentScript for IE10/11 (edge supports it).
|
||||
var src = opt_src || (document.currentScript && document.currentScript.src);
|
||||
callback(new Plugin(src));
|
||||
};
|
||||
|
||||
Gerrit.getLoggedIn = function() {
|
||||
return document.createElement('gr-rest-api-interface').getLoggedIn();
|
||||
};
|
||||
|
||||
Gerrit.installGwt = function() {
|
||||
// NOOP since PolyGerrit doesn’t support GWT plugins.
|
||||
};
|
||||
|
||||
@@ -75,6 +75,8 @@ limitations under the License.
|
||||
'shared/gr-date-formatter/gr-date-formatter_test.html',
|
||||
'shared/gr-editable-content/gr-editable-content_test.html',
|
||||
'shared/gr-editable-label/gr-editable-label_test.html',
|
||||
'shared/gr-js-api-interface/gr-change-actions-js-api_test.html',
|
||||
'shared/gr-js-api-interface/gr-change-reply-js-api_test.html',
|
||||
'shared/gr-js-api-interface/gr-js-api-interface_test.html',
|
||||
'shared/gr-linked-text/gr-linked-text_test.html',
|
||||
'shared/gr-rest-api-interface/gr-rest-api-interface_test.html',
|
||||
|
||||
Reference in New Issue
Block a user