Update iron-input to 2.0
This version is compatible with Polymer 1 and Polymer 2, but required for Polymer 2. Elements that were formerly <input is="iron-input> are now <iron-input> <input> </iron-input> There are a few scenarios in which inputs were not using two way data binding, which is the reason for using iron-input, and those have been modified back to a native input. With the updated iron-input to access the native input, there is an 'inputElement' getter function, which is used heavily in this update. Also of note, in many tests, it is required to wrap Polymer.Base.async, which is necessary because the mutation observer is async: https://github.com/PolymerElements/iron-input/blob/master/test/iron-input.html Also modifies polylint_test to explicitly ignore bower_components. Change-Id: I75f7fa1bb0c00837f631f6e1043e15a3270b9bce
This commit is contained in:
@@ -1062,8 +1062,8 @@ bower_archive(
|
||||
bower_archive(
|
||||
name = "iron-input",
|
||||
package = "polymerelements/iron-input",
|
||||
sha1 = "9bc0c8e81de2527125383cbcf74dd9f27e7fa9ac",
|
||||
version = "1.0.10",
|
||||
sha1 = "42f233d8adf3883bcce2fa364c7785a5d2571db4",
|
||||
version = "2.0.0",
|
||||
)
|
||||
|
||||
bower_archive(
|
||||
|
||||
@@ -25,8 +25,8 @@ def load_bower_archives():
|
||||
bower_archive(
|
||||
name = "iron-a11y-announcer",
|
||||
package = "iron-a11y-announcer",
|
||||
version = "1.0.5",
|
||||
sha1 = "007902c041dd8863a1fe893f62450852f4d8c69b")
|
||||
version = "2.0.0",
|
||||
sha1 = "8a7cc8d63eab3c068e0f8fcf4bf129a85922edc6")
|
||||
bower_archive(
|
||||
name = "iron-a11y-keys-behavior",
|
||||
package = "iron-a11y-keys-behavior",
|
||||
@@ -35,38 +35,38 @@ def load_bower_archives():
|
||||
bower_archive(
|
||||
name = "iron-behaviors",
|
||||
package = "iron-behaviors",
|
||||
version = "1.0.17",
|
||||
sha1 = "47df7e1c2b97978dcafa13edb50fbdb702570acd")
|
||||
version = "1.0.18",
|
||||
sha1 = "e231a1a02b090f5183db917639fdb96cdd0dca18")
|
||||
bower_archive(
|
||||
name = "iron-fit-behavior",
|
||||
package = "iron-fit-behavior",
|
||||
version = "1.2.6",
|
||||
sha1 = "59daa8526aac59aa72b8edcbbd24d9eed555a0f5")
|
||||
version = "1.2.7",
|
||||
sha1 = "01c485fbf898307029bbb72ac7e132db1570a842")
|
||||
bower_archive(
|
||||
name = "iron-flex-layout",
|
||||
package = "iron-flex-layout",
|
||||
version = "1.3.2",
|
||||
sha1 = "b896041aad049a5e889a0165828d7b1262e32612")
|
||||
version = "1.3.7",
|
||||
sha1 = "4d4cf3232cf750a17a7df0a37476117f831ac633")
|
||||
bower_archive(
|
||||
name = "iron-form-element-behavior",
|
||||
package = "iron-form-element-behavior",
|
||||
version = "1.0.6",
|
||||
sha1 = "8d9e6530edc1b99bec1a5c34853911fba3701220")
|
||||
version = "1.0.7",
|
||||
sha1 = "7b5a79e02cc32f0918725dd26925d0df1e03ed12")
|
||||
bower_archive(
|
||||
name = "iron-meta",
|
||||
package = "iron-meta",
|
||||
version = "1.1.2",
|
||||
sha1 = "dc22fe05e1cb5f94f30a7193d3433ca1808773b8")
|
||||
version = "1.1.3",
|
||||
sha1 = "f77eba3f6f6817f10bda33918bde8f963d450041")
|
||||
bower_archive(
|
||||
name = "iron-resizable-behavior",
|
||||
package = "iron-resizable-behavior",
|
||||
version = "1.0.5",
|
||||
sha1 = "2ebe983377dceb3794dd335131050656e23e2beb")
|
||||
version = "1.0.6",
|
||||
sha1 = "719c2a8a1a784f8aefcdeef41fcc2e5a03518d9e")
|
||||
bower_archive(
|
||||
name = "iron-validatable-behavior",
|
||||
package = "iron-validatable-behavior",
|
||||
version = "1.1.1",
|
||||
sha1 = "480423380be0536f948735d91bc472f6e7ced5b4")
|
||||
version = "1.1.2",
|
||||
sha1 = "7111f34ff32e1510131dfbdb1eaa51bfa291e8be")
|
||||
bower_archive(
|
||||
name = "lodash",
|
||||
package = "lodash",
|
||||
@@ -75,18 +75,18 @@ def load_bower_archives():
|
||||
bower_archive(
|
||||
name = "mocha",
|
||||
package = "mocha",
|
||||
version = "3.2.0",
|
||||
sha1 = "b77f23f7ad1f1363501bcae96f0f4f47745dad0f")
|
||||
version = "3.4.2",
|
||||
sha1 = "dfa9fd7705c541e8df3bfa22ca83789920024258")
|
||||
bower_archive(
|
||||
name = "neon-animation",
|
||||
package = "neon-animation",
|
||||
version = "1.2.4",
|
||||
sha1 = "e8ccbb930c4b7ff470b1450baa901618888a7fd3")
|
||||
version = "1.2.5",
|
||||
sha1 = "588d289f779d02b21ce5b676e257bbd6155649e8")
|
||||
bower_archive(
|
||||
name = "sinon-chai",
|
||||
package = "sinon-chai",
|
||||
version = "2.8.0",
|
||||
sha1 = "0464b5d944fdf8116bb23e0b02ecfbac945b3517")
|
||||
version = "2.11.0",
|
||||
sha1 = "3facb0ee3d4e06b8cd444c76e2fcb6d8b2ae3091")
|
||||
bower_archive(
|
||||
name = "sinonjs",
|
||||
package = "sinonjs",
|
||||
@@ -100,8 +100,8 @@ def load_bower_archives():
|
||||
bower_archive(
|
||||
name = "web-animations-js",
|
||||
package = "web-animations-js",
|
||||
version = "2.2.2",
|
||||
sha1 = "6276a9f227da7d4ccaf77c202b50e174dd11a2c2")
|
||||
version = "2.2.5",
|
||||
sha1 = "078116d92a15ec4def5ca2be2cd09b331efc1eb7")
|
||||
bower_archive(
|
||||
name = "webcomponentsjs",
|
||||
package = "webcomponentsjs",
|
||||
|
||||
@@ -167,12 +167,6 @@ def define_bower_components():
|
||||
license = "//lib:LICENSE-page.js",
|
||||
seed = True,
|
||||
)
|
||||
bower_component(
|
||||
name = "polymer",
|
||||
license = "//lib:LICENSE-polymer",
|
||||
deps = [ ":webcomponentsjs" ],
|
||||
seed = True,
|
||||
)
|
||||
bower_component(
|
||||
name = "polymer-resin",
|
||||
license = "//lib:LICENSE-polymer",
|
||||
@@ -182,6 +176,12 @@ def define_bower_components():
|
||||
],
|
||||
seed = True,
|
||||
)
|
||||
bower_component(
|
||||
name = "polymer",
|
||||
license = "//lib:LICENSE-polymer",
|
||||
deps = [ ":webcomponentsjs" ],
|
||||
seed = True,
|
||||
)
|
||||
bower_component(
|
||||
name = "promise-polyfill",
|
||||
license = "//lib:LICENSE-promise-polyfill",
|
||||
|
||||
@@ -38,10 +38,11 @@ limitations under the License.
|
||||
<div id="form">
|
||||
<section>
|
||||
<span class="title">Group name</span>
|
||||
<input
|
||||
is="iron-input"
|
||||
<iron-input
|
||||
id="groupNameInput"
|
||||
bind-value="{{_name}}">
|
||||
<input type="text">
|
||||
</iron-input>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
notify: true,
|
||||
value: false,
|
||||
},
|
||||
_name: Object,
|
||||
_name: String,
|
||||
_groupCreated: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
|
||||
@@ -50,13 +50,14 @@ limitations under the License.
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('name is updated correctly', () => {
|
||||
assert.isFalse(element.hasNewGroupName);
|
||||
|
||||
element.$.groupNameInput.bindValue = GROUP_NAME;
|
||||
|
||||
assert.isTrue(element.hasNewGroupName);
|
||||
assert.deepEqual(element._name, GROUP_NAME);
|
||||
test('name is updated correctly', done => {
|
||||
Polymer.Base.async(() => {
|
||||
assert.isFalse(element.hasNewGroupName);
|
||||
element.$.groupNameInput.bindValue = GROUP_NAME;
|
||||
assert.isTrue(element.hasNewGroupName);
|
||||
assert.deepEqual(element._name, GROUP_NAME);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('test for redirecting to group on successful creation', done => {
|
||||
|
||||
@@ -53,10 +53,11 @@ limitations under the License.
|
||||
<div id="form">
|
||||
<section>
|
||||
<span class="title">Project name</span>
|
||||
<input is="iron-input"
|
||||
<iron-input
|
||||
id="projectNameInput"
|
||||
autocomplete="on"
|
||||
bind-value="{{_projectConfig.name}}">
|
||||
<input autocomplete="on">
|
||||
</iron-input>
|
||||
</section>
|
||||
<section>
|
||||
<span class="title">Rights inherit from</span>
|
||||
|
||||
@@ -170,12 +170,13 @@ limitations under the License.
|
||||
<section>
|
||||
<span class="title">Maximum Git object size limit</span>
|
||||
<span class="value">
|
||||
<input
|
||||
<iron-input
|
||||
id="maxGitObjSizeInput"
|
||||
bind-value="{{_projectConfig.max_object_size_limit.configured_value}}"
|
||||
is="iron-input"
|
||||
type="text"
|
||||
disabled$="[[_readOnly]]">
|
||||
bind-value="{{_projectConfig.max_object_size_limit.configured_value}}">
|
||||
<input
|
||||
type="text"
|
||||
disabled$="[[_readOnly]]">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
},
|
||||
|
||||
_handleInputKeydown(e) {
|
||||
const input = e.detail.input;
|
||||
const input = e.detail.input.inputElement;
|
||||
if (input.selectionStart !== input.selectionEnd ||
|
||||
input.selectionStart !== 0) {
|
||||
return;
|
||||
|
||||
@@ -329,42 +329,51 @@ limitations under the License.
|
||||
});
|
||||
|
||||
suite('keyboard interactions', () => {
|
||||
test('backspace at text input start removes last account', () => {
|
||||
const input = element.$.entry.$.input;
|
||||
sandbox.stub(element.$.entry, '_getReviewerSuggestions');
|
||||
sandbox.stub(input, '_updateSuggestions');
|
||||
sandbox.stub(element, '_computeRemovable').returns(true);
|
||||
// Next line is a workaround for Firefix not moving cursor
|
||||
// on input field update
|
||||
assert.equal(input.$.input.selectionStart, 0);
|
||||
input.text = 'test';
|
||||
MockInteractions.focus(input.$.input);
|
||||
flushAsynchronousOperations();
|
||||
assert.equal(element.accounts.length, 2);
|
||||
MockInteractions.pressAndReleaseKeyOn(input.$.input, 8); // Backspace
|
||||
assert.equal(element.accounts.length, 2);
|
||||
input.text = '';
|
||||
MockInteractions.pressAndReleaseKeyOn(input.$.input, 8); // Backspace
|
||||
assert.equal(element.accounts.length, 1);
|
||||
test('backspace at text input start removes last account', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const autocomplete = element.$.entry.$.input;
|
||||
sandbox.stub(element.$.entry, '_getReviewerSuggestions');
|
||||
sandbox.stub(autocomplete, '_updateSuggestions');
|
||||
sandbox.stub(element, '_computeRemovable').returns(true);
|
||||
// Next line is a workaround for Firefix not moving cursor
|
||||
// on input field update
|
||||
assert.equal(autocomplete.$.input.inputElement.selectionStart, 0);
|
||||
autocomplete.text = 'test';
|
||||
MockInteractions.focus(autocomplete.$.input.inputElement);
|
||||
flushAsynchronousOperations();
|
||||
assert.equal(element.accounts.length, 2);
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
autocomplete.$.input.inputElement, 8); // Backspace
|
||||
assert.equal(element.accounts.length, 2);
|
||||
autocomplete.text = '';
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
autocomplete.$.input.inputElement, 8); // Backspace
|
||||
assert.equal(element.accounts.length, 1);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('arrow key navigation', () => {
|
||||
const input = element.$.entry.$.input;
|
||||
input.text = '';
|
||||
element.accounts = [makeAccount(), makeAccount()];
|
||||
MockInteractions.focus(input.$.input);
|
||||
flushAsynchronousOperations();
|
||||
const chips = element.accountChips;
|
||||
const chipsOneSpy = sandbox.spy(chips[1], 'focus');
|
||||
MockInteractions.pressAndReleaseKeyOn(input.$.input, 37); // Left
|
||||
assert.isTrue(chipsOneSpy.called);
|
||||
const chipsZeroSpy = sandbox.spy(chips[0], 'focus');
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[1], 37); // Left
|
||||
assert.isTrue(chipsZeroSpy.called);
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[0], 37); // Left
|
||||
assert.isTrue(chipsZeroSpy.calledOnce);
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[0], 39); // Right
|
||||
assert.isTrue(chipsOneSpy.calledTwice);
|
||||
test('arrow key navigation', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const autocomplete = element.$.entry.$.input;
|
||||
autocomplete.text = '';
|
||||
element.accounts = [makeAccount(), makeAccount()];
|
||||
MockInteractions.focus(autocomplete.$.input);
|
||||
flushAsynchronousOperations();
|
||||
const chips = element.accountChips;
|
||||
const chipsOneSpy = sandbox.spy(chips[1], 'focus');
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
autocomplete.$.input.inputElement, 37); // Left
|
||||
assert.isTrue(chipsOneSpy.called);
|
||||
const chipsZeroSpy = sandbox.spy(chips[0], 'focus');
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[1], 37); // Left
|
||||
assert.isTrue(chipsZeroSpy.called);
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[0], 37); // Left
|
||||
assert.isTrue(chipsZeroSpy.calledOnce);
|
||||
MockInteractions.pressAndReleaseKeyOn(chips[0], 39); // Right
|
||||
assert.isTrue(chipsOneSpy.calledTwice);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('delete', done => {
|
||||
|
||||
@@ -61,11 +61,11 @@ limitations under the License.
|
||||
<label for="branchInput">
|
||||
Cherry Pick to branch
|
||||
</label>
|
||||
<input is="iron-input"
|
||||
type="text"
|
||||
<iron-input
|
||||
id="branchInput"
|
||||
bind-value="{{branch}}"
|
||||
placeholder="Destination branch">
|
||||
bind-value="{{branch}}">
|
||||
<input type="text" placeholder="Destination branch">
|
||||
</iron-input>
|
||||
<label for="messageInput">
|
||||
Cherry Pick Commit Message
|
||||
</label>
|
||||
|
||||
@@ -98,12 +98,12 @@ limitations under the License.
|
||||
</label>
|
||||
</div>
|
||||
<div class="parentRevisionContainer">
|
||||
<input is="iron-input"
|
||||
type="text"
|
||||
<iron-input
|
||||
id="parentInput"
|
||||
bind-value="{{base}}"
|
||||
on-tap="_handleEnterChangeNumberTap"
|
||||
placeholder="Change number">
|
||||
on-tap="_handleEnterChangeNumberTap">
|
||||
<input type="text" placeholder="Change number">
|
||||
</iron-input>
|
||||
</div>
|
||||
</div>
|
||||
</gr-confirm-dialog>
|
||||
|
||||
@@ -391,10 +391,14 @@
|
||||
.focus.bind(textarea.getNativeTextarea()));
|
||||
} else if (section === FocusTarget.REVIEWERS) {
|
||||
const reviewerEntry = this.$.reviewers.focusStart;
|
||||
reviewerEntry.async(reviewerEntry.focus);
|
||||
Polymer.Base.async(() => {
|
||||
reviewerEntry.inputElement.focus();
|
||||
}, 1);
|
||||
} else if (section === FocusTarget.CCS) {
|
||||
const ccEntry = this.$$('#ccs').focusStart;
|
||||
ccEntry.async(ccEntry.focus);
|
||||
Polymer.Base.async(() => {
|
||||
ccEntry.inputElement.focus();
|
||||
}, 1);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -267,6 +267,14 @@ limitations under the License.
|
||||
});
|
||||
}
|
||||
|
||||
function testAsync(testFunc) {
|
||||
return new Promise(resolve => {
|
||||
Polymer.Base.async(() => {
|
||||
resolve(testFunc());
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
|
||||
function testConfirmationDialog(done, cc) {
|
||||
const yesButton =
|
||||
element.$$('.reviewerConfirmationButtons gr-button:first-child');
|
||||
@@ -318,55 +326,59 @@ limitations under the License.
|
||||
MockInteractions.tap(noButton); // close the overlay
|
||||
return observer;
|
||||
}).then(() => {
|
||||
assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
|
||||
return testAsync(() => {
|
||||
assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
|
||||
|
||||
// We should be focused on account entry input.
|
||||
assert.equal(getActiveElement().id, 'input');
|
||||
// We should be focused on account entry input.
|
||||
assert.equal(getActiveElement().tagName, 'INPUT');
|
||||
|
||||
// No reviewer/CC should have been added.
|
||||
assert.equal(element.$$('#ccs').additions().length, 0);
|
||||
assert.equal(element.$.reviewers.additions().length, 0);
|
||||
// No reviewer/CC should have been added.
|
||||
assert.equal(element.$$('#ccs').additions().length, 0);
|
||||
assert.equal(element.$.reviewers.additions().length, 0);
|
||||
|
||||
// Reopen confirmation dialog.
|
||||
observer = overlayObserver('opened');
|
||||
if (cc) {
|
||||
element._ccPendingConfirmation = {
|
||||
group,
|
||||
count: 10,
|
||||
};
|
||||
} else {
|
||||
element._reviewerPendingConfirmation = {
|
||||
group,
|
||||
count: 10,
|
||||
};
|
||||
}
|
||||
return observer;
|
||||
}).then(() => {
|
||||
// Reopen confirmation dialog.
|
||||
observer = overlayObserver('opened');
|
||||
if (cc) {
|
||||
element._ccPendingConfirmation = {
|
||||
group,
|
||||
count: 10,
|
||||
};
|
||||
} else {
|
||||
element._reviewerPendingConfirmation = {
|
||||
group,
|
||||
count: 10,
|
||||
};
|
||||
}
|
||||
return observer;
|
||||
});
|
||||
}).then(x => {
|
||||
assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
|
||||
observer = overlayObserver('closed');
|
||||
MockInteractions.tap(yesButton); // Confirm the group.
|
||||
return observer;
|
||||
}).then(() => {
|
||||
assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
|
||||
const additions = cc ?
|
||||
element.$$('#ccs').additions() :
|
||||
element.$.reviewers.additions();
|
||||
assert.deepEqual(
|
||||
additions,
|
||||
[
|
||||
{
|
||||
group: {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
confirmed: true,
|
||||
_group: true,
|
||||
_pendingAdd: true,
|
||||
return testAsync(() => {
|
||||
assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
|
||||
const additions = cc ?
|
||||
element.$$('#ccs').additions() :
|
||||
element.$.reviewers.additions();
|
||||
assert.deepEqual(
|
||||
additions,
|
||||
[
|
||||
{
|
||||
group: {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
confirmed: true,
|
||||
_group: true,
|
||||
_pendingAdd: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
]);
|
||||
|
||||
// We should be focused on account entry input.
|
||||
assert.equal(getActiveElement().id, 'input');
|
||||
// We should be focused on account entry input.
|
||||
assert.equal(getActiveElement().tagName, 'INPUT');
|
||||
});
|
||||
}).then(done);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,35 +65,47 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('enter in search input triggers nav', done => {
|
||||
sinon.stub(page, 'show', () => {
|
||||
page.show.restore();
|
||||
assert.notEqual(getActiveElement(), element.$.searchInput);
|
||||
assert.notEqual(getActiveElement(), element.$.searchButton);
|
||||
Polymer.Base.async(() => {
|
||||
sinon.stub(page, 'show', () => {
|
||||
page.show.restore();
|
||||
assert.notEqual(getActiveElement(), element.$.searchInput);
|
||||
assert.notEqual(getActiveElement(), element.$.searchButton);
|
||||
done();
|
||||
});
|
||||
element.value = 'test';
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
element.$.searchInput.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('search query should be double-escaped', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const showStub = sinon.stub(page, 'show');
|
||||
element.$.searchInput.text = 'fate/stay';
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
element.$.searchInput.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
assert.equal(showStub.lastCall.args[0], '/q/fate%252Fstay');
|
||||
showStub.restore();
|
||||
done();
|
||||
});
|
||||
element.value = 'test';
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
|
||||
null, 'enter');
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('search query should be double-escaped', () => {
|
||||
const showStub = sinon.stub(page, 'show');
|
||||
element.$.searchInput.text = 'fate/stay';
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
|
||||
null, 'enter');
|
||||
assert.equal(showStub.lastCall.args[0], '/q/fate%252Fstay');
|
||||
showStub.restore();
|
||||
});
|
||||
|
||||
test('input blurred after commit', () => {
|
||||
const showStub = sinon.stub(page, 'show');
|
||||
const blurSpy = sinon.spy(element.$.searchInput.$.input, 'blur');
|
||||
element.$.searchInput.text = 'fate/stay';
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
|
||||
null, 'enter');
|
||||
assert.isTrue(blurSpy.called);
|
||||
showStub.restore();
|
||||
blurSpy.restore();
|
||||
test('input blurred after commit', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const showStub = sinon.stub(page, 'show');
|
||||
const blurSpy = sinon.spy(
|
||||
element.$.searchInput.$.input, 'blur');
|
||||
element.$.searchInput.text = 'fate/stay';
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
element.$.searchInput.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
assert.isTrue(blurSpy.called);
|
||||
showStub.restore();
|
||||
blurSpy.restore();
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('empty search query does not trigger nav', () => {
|
||||
@@ -104,12 +116,14 @@ limitations under the License.
|
||||
assert.isFalse(showSpy.called);
|
||||
});
|
||||
|
||||
test('keyboard shortcuts', () => {
|
||||
const focusSpy = sinon.spy(element.$.searchInput, 'focus');
|
||||
const selectAllSpy = sinon.spy(element.$.searchInput, 'selectAll');
|
||||
MockInteractions.pressAndReleaseKeyOn(document.body, 191, null, '/');
|
||||
assert.isTrue(focusSpy.called);
|
||||
assert.isTrue(selectAllSpy.called);
|
||||
test('keyboard shortcuts', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const focusSpy = sinon.spy(element.$.searchInput, 'focus');
|
||||
const selectAllSpy = sinon.spy(element.$.searchInput, 'selectAll');
|
||||
MockInteractions.pressAndReleaseKeyOn(document.body, 191, null, '/');
|
||||
assert.isTrue(focusSpy.called);
|
||||
assert.isTrue(selectAllSpy.called); done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
suite('_getSearchSuggestions', () => {
|
||||
|
||||
@@ -93,49 +93,58 @@ limitations under the License.
|
||||
</div>
|
||||
<div class="pref">
|
||||
<label for="lineWrappingInput">Fit to screen</label>
|
||||
<input
|
||||
is="iron-input"
|
||||
type="checkbox"
|
||||
<input type="checkbox"
|
||||
id="lineWrappingInput"
|
||||
on-tap="_handlelineWrappingTap">
|
||||
</div>
|
||||
<div class="pref" id="columnsPref"
|
||||
hidden$="[[_newPrefs.line_wrapping]]">
|
||||
<label for="columnsInput">Diff width</label>
|
||||
<input is="iron-input" type="number" id="columnsInput"
|
||||
prevent-invalid-input
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_newPrefs.line_length}}">
|
||||
<iron-input
|
||||
id="columnsInput"
|
||||
bind-value="{{_newPrefs.line_length}}"
|
||||
allowed-pattern="[0-9]">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</div>
|
||||
<div class="pref">
|
||||
<label for="tabSizeInput">Tab width</label>
|
||||
<input is="iron-input" type="number" id="tabSizeInput"
|
||||
prevent-invalid-input
|
||||
<iron-input
|
||||
id="tabSizeInput"
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_newPrefs.tab_size}}">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</div>
|
||||
<div class="pref" hidden$="[[!_newPrefs.font_size]]">
|
||||
<label for="fontSizeInput">Font size</label>
|
||||
<input is="iron-input" type="number" id="fontSizeInput"
|
||||
prevent-invalid-input
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_newPrefs.font_size}}">
|
||||
<iron-input
|
||||
id="fontSizeInput"
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_newPrefs.font_size}}">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</div>
|
||||
<div class="pref">
|
||||
<label for="showTabsInput">Show tabs</label>
|
||||
<input is="iron-input" type="checkbox" id="showTabsInput"
|
||||
<input
|
||||
type="checkbox"
|
||||
id="showTabsInput"
|
||||
on-tap="_handleShowTabsTap">
|
||||
</div>
|
||||
<div class="pref">
|
||||
<label for="showTrailingWhitespaceInput">
|
||||
Show trailing whitespace</label>
|
||||
<input is="iron-input" type="checkbox"
|
||||
<input
|
||||
id="showTrailingWhitespaceInput"
|
||||
type="checkbox"
|
||||
on-tap="_handleShowTrailingWhitespaceTap">
|
||||
</div>
|
||||
<div class="pref">
|
||||
<label for="syntaxHighlightInput">Syntax highlighting</label>
|
||||
<input is="iron-input" type="checkbox" id="syntaxHighlightInput"
|
||||
<input
|
||||
id="syntaxHighlightInput"
|
||||
type="checkbox"
|
||||
on-tap="_handleSyntaxHighlightTap">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,36 +45,39 @@ limitations under the License.
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('model changes', () => {
|
||||
element.prefs = {
|
||||
context: 10,
|
||||
font_size: 12,
|
||||
line_length: 100,
|
||||
show_tabs: true,
|
||||
tab_size: 8,
|
||||
show_whitespace_errors: true,
|
||||
syntax_highlighting: true,
|
||||
};
|
||||
assert.deepEqual(element.prefs, element._newPrefs);
|
||||
test('model changes', done => {
|
||||
Polymer.Base.async(() => {
|
||||
element.prefs = {
|
||||
context: 10,
|
||||
font_size: 12,
|
||||
line_length: 100,
|
||||
show_tabs: true,
|
||||
tab_size: 8,
|
||||
show_whitespace_errors: true,
|
||||
syntax_highlighting: true,
|
||||
};
|
||||
assert.deepEqual(element.prefs, element._newPrefs);
|
||||
|
||||
element.$.contextSelect.value = '50';
|
||||
element.fire('change', {}, {node: element.$.contextSelect});
|
||||
element.$.columnsInput.bindValue = 80;
|
||||
element.$.fontSizeInput.bindValue = 10;
|
||||
element.$.tabSizeInput.bindValue = 4;
|
||||
MockInteractions.tap(element.$.showTabsInput);
|
||||
MockInteractions.tap(element.$.showTrailingWhitespaceInput);
|
||||
MockInteractions.tap(element.$.syntaxHighlightInput);
|
||||
MockInteractions.tap(element.$.lineWrappingInput);
|
||||
element.$.contextSelect.value = '50';
|
||||
element.fire('change', {}, {node: element.$.contextSelect});
|
||||
element.$.columnsInput.bindValue = 80;
|
||||
element.$.fontSizeInput.bindValue = 10;
|
||||
element.$.tabSizeInput.bindValue = 4;
|
||||
MockInteractions.tap(element.$.showTabsInput);
|
||||
MockInteractions.tap(element.$.showTrailingWhitespaceInput);
|
||||
MockInteractions.tap(element.$.syntaxHighlightInput);
|
||||
MockInteractions.tap(element.$.lineWrappingInput);
|
||||
|
||||
assert.equal(element._newPrefs.context, 50);
|
||||
assert.equal(element._newPrefs.font_size, 10);
|
||||
assert.equal(element._newPrefs.line_length, 80);
|
||||
assert.equal(element._newPrefs.tab_size, 4);
|
||||
assert.isFalse(element._newPrefs.show_tabs);
|
||||
assert.isFalse(element._newPrefs.show_whitespace_errors);
|
||||
assert.isTrue(element._newPrefs.line_wrapping);
|
||||
assert.isFalse(element._newPrefs.syntax_highlighting);
|
||||
assert.equal(element._newPrefs.context, 50);
|
||||
assert.equal(element._newPrefs.font_size, 10);
|
||||
assert.equal(element._newPrefs.line_length, 80);
|
||||
assert.equal(element._newPrefs.tab_size, 4);
|
||||
assert.isFalse(element._newPrefs.show_tabs);
|
||||
assert.isFalse(element._newPrefs.show_whitespace_errors);
|
||||
assert.isTrue(element._newPrefs.line_wrapping);
|
||||
assert.isFalse(element._newPrefs.syntax_highlighting);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('clicking fit to screen hides line length input', () => {
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
|
||||
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
@@ -56,24 +57,25 @@ limitations under the License.
|
||||
<span
|
||||
hidden$="[[!mutable]]"
|
||||
class="value">
|
||||
<input
|
||||
is="iron-input"
|
||||
<iron-input
|
||||
id="nameInput"
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleKeydown"
|
||||
bind-value="{{_account.name}}">
|
||||
<input disabled="[[_saving]]"
|
||||
on-keydown="_handleKeydown">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section>
|
||||
<span class="title">Status</span>
|
||||
<span class="value">
|
||||
<input
|
||||
is="iron-input"
|
||||
<iron-input
|
||||
id="statusInput"
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleKeydown"
|
||||
bind-value="{{_account.status}}">
|
||||
</span>
|
||||
<input
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleKeydown">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
</div>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
|
||||
@@ -128,23 +128,26 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('name', done => {
|
||||
assert.isTrue(element.mutable);
|
||||
assert.isFalse(element.hasUnsavedChanges);
|
||||
Polymer.Base.async(() => {
|
||||
assert.isTrue(element.mutable);
|
||||
assert.isFalse(element.hasUnsavedChanges);
|
||||
|
||||
element.set('_account.name', 'new name');
|
||||
element.set('_account.name', 'new name');
|
||||
|
||||
assert.isTrue(nameChangedSpy.called);
|
||||
assert.isFalse(statusChangedSpy.called);
|
||||
assert.isTrue(element.hasUnsavedChanges);
|
||||
assert.isTrue(nameChangedSpy.called);
|
||||
assert.isFalse(statusChangedSpy.called);
|
||||
assert.isTrue(element.hasUnsavedChanges);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.nameInput, 13);
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
element.$.nameInput.inputElement, 13);
|
||||
|
||||
assert.isTrue(nameStub.called);
|
||||
assert.isFalse(statusStub.called);
|
||||
nameStub.lastCall.returnValue.then(() => {
|
||||
assert.equal(nameStub.lastCall.args[0], 'new name');
|
||||
done();
|
||||
});
|
||||
assert.isTrue(nameStub.called);
|
||||
assert.isFalse(statusStub.called);
|
||||
nameStub.lastCall.returnValue.then(() => {
|
||||
assert.equal(nameStub.lastCall.args[0], 'new name');
|
||||
done();
|
||||
});
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('status', done => {
|
||||
|
||||
@@ -15,7 +15,6 @@ limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
@@ -63,7 +62,6 @@ limitations under the License.
|
||||
<td class="emailColumn">[[item.email]]</td>
|
||||
<td class="preferredControl" on-tap="_handlePreferredControlTap">
|
||||
<input
|
||||
is="iron-input"
|
||||
class="preferredRadio"
|
||||
type="radio"
|
||||
on-change="_handlePreferredChange"
|
||||
|
||||
@@ -81,19 +81,22 @@ limitations under the License.
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>
|
||||
<input
|
||||
is="iron-input"
|
||||
placeholder="New Title"
|
||||
on-keydown="_handleInputKeydown"
|
||||
bind-value="{{_newName}}">
|
||||
<iron-input bind-value="{{_newName}}">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="New Title"
|
||||
on-keydown="_handleInputKeydown">
|
||||
</iron-input>
|
||||
</th>
|
||||
<th>
|
||||
<input
|
||||
<iron-input
|
||||
class="newUrlInput"
|
||||
is="iron-input"
|
||||
placeholder="New URL"
|
||||
on-keydown="_handleInputKeydown"
|
||||
bind-value="{{_newUrl}}">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="New URL"
|
||||
on-keydown="_handleInputKeydown">
|
||||
</iron-input>
|
||||
</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
|
||||
_computeAddDisabled(newName, newUrl) {
|
||||
return !newName.length || !newUrl.length;
|
||||
return !newName || !newUrl;
|
||||
},
|
||||
|
||||
_handleInputKeydown(e) {
|
||||
|
||||
@@ -64,19 +64,22 @@ limitations under the License.
|
||||
Polymer.dom.flush();
|
||||
});
|
||||
|
||||
test('renders', () => {
|
||||
test('renders', done => {
|
||||
const rows = element.$$('tbody').querySelectorAll('tr');
|
||||
let tds;
|
||||
|
||||
assert.equal(rows.length, menu.length);
|
||||
for (let i = 0; i < menu.length; i++) {
|
||||
tds = rows[i].querySelectorAll('td');
|
||||
assert.equal(tds[0].textContent, menu[i].name);
|
||||
assert.equal(tds[1].textContent, menu[i].url);
|
||||
}
|
||||
Polymer.Base.async(() => {
|
||||
assert.equal(rows.length, menu.length);
|
||||
for (let i = 0; i < menu.length; i++) {
|
||||
tds = rows[i].querySelectorAll('td');
|
||||
assert.equal(tds[0].textContent, menu[i].name);
|
||||
assert.equal(tds[1].textContent, menu[i].url);
|
||||
}
|
||||
|
||||
assert.isTrue(element._computeAddDisabled(element._newName,
|
||||
element._newUrl));
|
||||
assert.isTrue(element._computeAddDisabled(element._newName,
|
||||
element._newUrl));
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('_computeAddDisabled', () => {
|
||||
@@ -86,23 +89,27 @@ limitations under the License.
|
||||
assert.isFalse(element._computeAddDisabled('name', 'url'));
|
||||
});
|
||||
|
||||
test('add a new menu item', () => {
|
||||
test('add a new menu item', done => {
|
||||
const newName = 'new name';
|
||||
const newUrl = 'new url';
|
||||
|
||||
element._newName = newName;
|
||||
element._newUrl = newUrl;
|
||||
assert.isFalse(element._computeAddDisabled(element._newName,
|
||||
element._newUrl));
|
||||
Polymer.Base.async(() => {
|
||||
element._newName = newName;
|
||||
element._newUrl = newUrl;
|
||||
|
||||
const originalMenuLength = element.menuItems.length;
|
||||
assert.isFalse(element._computeAddDisabled(element._newName,
|
||||
element._newUrl));
|
||||
|
||||
element._handleAddButton();
|
||||
const originalMenuLength = element.menuItems.length;
|
||||
|
||||
assert.equal(element.menuItems.length, originalMenuLength + 1);
|
||||
assert.equal(element.menuItems[element.menuItems.length - 1].name,
|
||||
newName);
|
||||
assert.equal(element.menuItems[element.menuItems.length - 1].url, newUrl);
|
||||
element._handleAddButton();
|
||||
|
||||
assert.equal(element.menuItems.length, originalMenuLength + 1);
|
||||
assert.equal(element.menuItems[element.menuItems.length - 1].name,
|
||||
newName);
|
||||
assert.equal(element.menuItems[element.menuItems.length - 1].url, newUrl);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('move items down', () => {
|
||||
|
||||
@@ -15,10 +15,11 @@ limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="../../../styles/gr-form-styles.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
|
||||
<dom-module id="gr-registration-dialog">
|
||||
<template>
|
||||
@@ -60,12 +61,11 @@ limitations under the License.
|
||||
<hr>
|
||||
<section>
|
||||
<div class="title">Full Name</div>
|
||||
<input
|
||||
is="iron-input"
|
||||
id="name"
|
||||
bind-value="{{_account.name}}"
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleNameKeydown">
|
||||
<input
|
||||
id="name"
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleNameKeydown"
|
||||
value="[[_account.name]]">
|
||||
</section>
|
||||
<section>
|
||||
<div class="title">Preferred Email</div>
|
||||
|
||||
@@ -220,34 +220,31 @@ limitations under the License.
|
||||
<section id="columnsPref" hidden$="[[_diffPrefs.line_wrapping]]">
|
||||
<span class="title">Diff width</span>
|
||||
<span class="value">
|
||||
<input
|
||||
is="iron-input"
|
||||
type="number"
|
||||
prevent-invalid-input
|
||||
<iron-input
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_diffPrefs.line_length}}">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section>
|
||||
<span class="title">Tab width</span>
|
||||
<span class="value">
|
||||
<input
|
||||
is="iron-input"
|
||||
type="number"
|
||||
prevent-invalid-input
|
||||
<iron-input
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_diffPrefs.tab_size}}">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section hidden$="[[!_diffPrefs.font_size]]">
|
||||
<span class="title">Font size</span>
|
||||
<span class="value">
|
||||
<input
|
||||
is="iron-input"
|
||||
type="number"
|
||||
prevent-invalid-input
|
||||
allowed-pattern="[0-9]"
|
||||
<iron-input
|
||||
allowed-pattern="[0-9]"
|
||||
bind-value="{{_diffPrefs.font_size}}">
|
||||
<input type="number">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section>
|
||||
@@ -337,14 +334,15 @@ limitations under the License.
|
||||
<section>
|
||||
<span class="title">New email address</span>
|
||||
<span class="value">
|
||||
<input
|
||||
<iron-input
|
||||
id="newEmailInput"
|
||||
bind-value="{{_newEmail}}"
|
||||
is="iron-input"
|
||||
type="text"
|
||||
disabled="[[_addingEmail]]"
|
||||
on-keydown="_handleNewEmailKeydown"
|
||||
placeholder="email@example.com">
|
||||
bind-value="{{_newEmail}}">
|
||||
<input
|
||||
type="text"
|
||||
disabled="[[_addingEmail]]"
|
||||
on-keydown="_handleNewEmailKeydown"
|
||||
placeholder="email@example.com">
|
||||
</iron-input>
|
||||
</span>
|
||||
</section>
|
||||
<section
|
||||
|
||||
@@ -102,7 +102,6 @@ limitations under the License.
|
||||
<input
|
||||
id="newFilter"
|
||||
class="newFilterInput"
|
||||
is="iron-input"
|
||||
placeholder="branch:name, or other search expression">
|
||||
</th>
|
||||
<th>
|
||||
|
||||
@@ -161,7 +161,7 @@ limitations under the License.
|
||||
test('_handleAddProject', () => {
|
||||
element.$.newProject.value = {id: 'project d'};
|
||||
element.$.newProject.setText('project d');
|
||||
element.$.newFilter.bindValue = '';
|
||||
element.$.newFilter.value = '';
|
||||
|
||||
element._handleAddProject();
|
||||
|
||||
@@ -174,7 +174,7 @@ limitations under the License.
|
||||
test('_handleAddProject with invalid inputs', () => {
|
||||
element.$.newProject.value = {id: 'project b'};
|
||||
element.$.newProject.setText('project b');
|
||||
element.$.newFilter.bindValue = 'filter 1';
|
||||
element.$.newFilter.value = 'filter 1';
|
||||
|
||||
element._handleAddProject();
|
||||
|
||||
|
||||
@@ -23,32 +23,34 @@ limitations under the License.
|
||||
<dom-module id="gr-autocomplete">
|
||||
<template>
|
||||
<style include="shared-styles">
|
||||
input {
|
||||
iron-input, input {
|
||||
font-size: 1em;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
iron-input {
|
||||
@apply --gr-autocomplete;
|
||||
}
|
||||
input.borderless,
|
||||
input.borderless:focus {
|
||||
iron-input.borderless input,
|
||||
iron-input.borderless:focus input {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
input.warnUncommitted {
|
||||
iron-input.warnUncommitted input {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<input
|
||||
id="input"
|
||||
<iron-input id="input"
|
||||
class$="[[_computeClass(borderless)]]"
|
||||
is="iron-input"
|
||||
disabled$="[[disabled]]"
|
||||
bind-value="{{text}}"
|
||||
placeholder="[[placeholder]]"
|
||||
on-keydown="_handleKeydown"
|
||||
on-focus="_onInputFocus"
|
||||
on-blur="_onInputBlur"
|
||||
autocomplete="off" />
|
||||
bind-value="{{text}}">
|
||||
<input
|
||||
disabled$="[[disabled]]"
|
||||
placeholder="[[placeholder]]"
|
||||
on-keydown="_handleKeydown"
|
||||
on-focus="_onInputFocus"
|
||||
on-blur="_onInputBlur"
|
||||
autocomplete="off" />
|
||||
</iron-input>
|
||||
<!-- This container is needed for Safari and Firefox -->
|
||||
<div id="suggestionContainer">
|
||||
<gr-autocomplete-dropdown id="suggestions"
|
||||
|
||||
@@ -154,7 +154,8 @@
|
||||
},
|
||||
|
||||
selectAll() {
|
||||
this.$.input.setSelectionRange(0, this.$.input.value.length);
|
||||
this.$.input.inputElement.setSelectionRange(0,
|
||||
this.$.input.bindValue.length);
|
||||
},
|
||||
|
||||
clear() {
|
||||
|
||||
@@ -100,12 +100,14 @@ limitations under the License.
|
||||
const cancelHandler = sandbox.spy();
|
||||
element.addEventListener('cancel', cancelHandler);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 27, null, 'esc');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 27,
|
||||
null, 'esc');
|
||||
assert.isFalse(cancelHandler.called);
|
||||
assert.isTrue(element.$.suggestions.hidden);
|
||||
assert.equal(element._suggestions.length, 0);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 27, null, 'esc');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 27,
|
||||
null, 'esc');
|
||||
assert.isTrue(cancelHandler.called);
|
||||
done();
|
||||
});
|
||||
@@ -137,22 +139,23 @@ limitations under the License.
|
||||
|
||||
assert.equal(element.$.suggestions.$.cursor.index, 0);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 40, null,
|
||||
'down');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 40,
|
||||
null, 'down');
|
||||
|
||||
assert.equal(element.$.suggestions.$.cursor.index, 1);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 40, null,
|
||||
'down');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 40,
|
||||
null, 'down');
|
||||
|
||||
assert.equal(element.$.suggestions.$.cursor.index, 2);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 38, null, 'up');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 38,
|
||||
null, 'up');
|
||||
|
||||
assert.equal(element.$.suggestions.$.cursor.index, 1);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null,
|
||||
'enter');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
|
||||
assert.equal(element.value, 1);
|
||||
assert.isTrue(commitHandler.called);
|
||||
@@ -175,8 +178,8 @@ limitations under the License.
|
||||
const commitHandler = sandbox.spy();
|
||||
element.addEventListener('commit', commitHandler);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null,
|
||||
'enter');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
|
||||
assert.isTrue(commitHandler.called);
|
||||
assert.equal(element.text, 'suggestion');
|
||||
@@ -197,8 +200,8 @@ limitations under the License.
|
||||
const commitHandler = sandbox.spy();
|
||||
element.addEventListener('commit', commitHandler);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null,
|
||||
'enter');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
|
||||
assert.isTrue(commitHandler.called);
|
||||
assert.equal(element.text, '');
|
||||
@@ -248,8 +251,8 @@ limitations under the License.
|
||||
const commitHandler = sandbox.spy();
|
||||
element.addEventListener('commit', commitHandler);
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null,
|
||||
'enter');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
|
||||
assert.isTrue(commitHandler.called);
|
||||
assert.equal(element.text, 'blah 0');
|
||||
@@ -267,14 +270,16 @@ limitations under the License.
|
||||
|
||||
element._suggestions = ['tunnel snakes rule!'];
|
||||
element.tabComplete = false;
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 9,
|
||||
null, 'tab');
|
||||
assert.isFalse(commitHandler.called);
|
||||
assert.isFalse(commitSpy.called);
|
||||
assert.isFalse(element._focused);
|
||||
|
||||
element.tabComplete = true;
|
||||
element._focused = true;
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 9,
|
||||
null, 'tab');
|
||||
assert.isFalse(commitHandler.called);
|
||||
assert.isTrue(commitSpy.called);
|
||||
assert.isTrue(element._focused);
|
||||
@@ -307,8 +312,8 @@ limitations under the License.
|
||||
test('enter does not call focus', () => {
|
||||
element._suggestions = ['sugar bombs'];
|
||||
focusSpy = sandbox.spy(element, 'focus');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null,
|
||||
'enter');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 13,
|
||||
null, 'enter');
|
||||
flushAsynchronousOperations();
|
||||
|
||||
assert.isTrue(commitSpy.called);
|
||||
@@ -320,7 +325,8 @@ limitations under the License.
|
||||
element._suggestions = ['sugar bombs'];
|
||||
focusSpy = sandbox.spy(element, 'focus');
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 9,
|
||||
null, 'tab');
|
||||
flushAsynchronousOperations();
|
||||
|
||||
assert.isFalse(commitSpy.called);
|
||||
@@ -329,7 +335,8 @@ limitations under the License.
|
||||
|
||||
element.tabComplete = true;
|
||||
element._suggestions = ['tunnel snakes drool'];
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 9,
|
||||
null, 'tab');
|
||||
flushAsynchronousOperations();
|
||||
|
||||
assert.isTrue(commitSpy.called);
|
||||
@@ -386,12 +393,16 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('input-keydown event fired', () => {
|
||||
const listener = sandbox.spy();
|
||||
element.addEventListener('input-keydown', listener);
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
|
||||
flushAsynchronousOperations();
|
||||
assert.isTrue(listener.called);
|
||||
test('input-keydown event fired', done => {
|
||||
Polymer.Base.async(() => {
|
||||
const listener = sandbox.spy();
|
||||
element.addEventListener('input-keydown', listener);
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input.inputElement, 9,
|
||||
null, 'tab');
|
||||
flushAsynchronousOperations();
|
||||
assert.isTrue(listener.called);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
suite('warnUncommitted', () => {
|
||||
@@ -400,27 +411,36 @@ limitations under the License.
|
||||
inputClassList = element.$.input.classList;
|
||||
});
|
||||
|
||||
test('enabled', () => {
|
||||
element.warnUncommitted = true;
|
||||
element.text = 'blah blah blah';
|
||||
MockInteractions.blur(element.$.input);
|
||||
assert.isTrue(inputClassList.contains('warnUncommitted'));
|
||||
MockInteractions.focus(element.$.input);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
test('enabled', done => {
|
||||
Polymer.Base.async(() => {
|
||||
element.warnUncommitted = true;
|
||||
element.text = 'blah blah blah';
|
||||
MockInteractions.blur(element.$.input.inputElement);
|
||||
assert.isTrue(inputClassList.contains('warnUncommitted'));
|
||||
MockInteractions.focus(element.$.input.inputElement);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('disabled', () => {
|
||||
element.warnUncommitted = false;
|
||||
element.text = 'blah blah blah';
|
||||
MockInteractions.blur(element.$.input);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
test('disabled', done => {
|
||||
Polymer.Base.async(() => {
|
||||
element.warnUncommitted = false;
|
||||
element.text = 'blah blah blah';
|
||||
MockInteractions.blur(element.$.input.inputElement);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('no text', () => {
|
||||
element.warnUncommitted = true;
|
||||
element.text = '';
|
||||
MockInteractions.blur(element.$.input);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
test('no text', done => {
|
||||
Polymer.Base.async(() => {
|
||||
element.warnUncommitted = true;
|
||||
element.text = '';
|
||||
MockInteractions.blur(element.$.input.inputElement);
|
||||
assert.isFalse(inputClassList.contains('warnUncommitted'));
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,6 @@ limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
@@ -46,12 +45,13 @@ limitations under the License.
|
||||
</style>
|
||||
<div class="text">
|
||||
<label>[[title]]</label>
|
||||
<input id="input" is="iron-input"
|
||||
class$="copyText [[_computeInputClass(hideInput)]]"
|
||||
<input
|
||||
id="input"
|
||||
type="text"
|
||||
bind-value="[[text]]"
|
||||
on-tap="_handleInputTap"
|
||||
readonly>
|
||||
readonly
|
||||
class$="copyText [[_computeInputClass(hideInput)]]"
|
||||
value="[[text]]">
|
||||
<gr-button id="button"
|
||||
class="copyToClipboard"
|
||||
on-tap="_copyToClipboard">
|
||||
|
||||
@@ -45,11 +45,12 @@ limitations under the License.
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
<input
|
||||
is="iron-input"
|
||||
<iron-input
|
||||
id="input"
|
||||
hidden$="[[!editing]]"
|
||||
bind-value="{{_inputText}}">
|
||||
bind-value="{{_inputText}}"
|
||||
hidden$="[[!editing]]">
|
||||
<input>
|
||||
</iron-input>
|
||||
<label
|
||||
hidden$="[[editing]]"
|
||||
class$="[[_computeLabelClass(readOnly, value, placeholder)]]"
|
||||
|
||||
@@ -76,8 +76,9 @@
|
||||
this.editing = true;
|
||||
|
||||
this.async(() => {
|
||||
this.$.input.focus();
|
||||
this.$.input.setSelectionRange(0, this.$.input.value.length);
|
||||
this.$.input.inputElement.focus();
|
||||
this.$.input.inputElement
|
||||
.setSelectionRange(0, this.$.input.inputElement.value.length);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -99,7 +100,7 @@
|
||||
_handleEnter(e) {
|
||||
e = this.getKeyboardEvent(e);
|
||||
const target = Polymer.dom(e).rootTarget;
|
||||
if (target === this.$.input) {
|
||||
if (target === this.$.input.inputElement) {
|
||||
e.preventDefault();
|
||||
this._save();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ limitations under the License.
|
||||
setup(() => {
|
||||
element = fixture('basic');
|
||||
|
||||
input = element.$$('input');
|
||||
input = element.$$('iron-input');
|
||||
label = element.$$('label');
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
@@ -63,46 +63,51 @@ limitations under the License.
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('element render', () => {
|
||||
test('element render', done => {
|
||||
Polymer.Base.async(() => {
|
||||
// The input is hidden and the label is visible:
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
|
||||
assert.isTrue(label.classList.contains('editable'));
|
||||
assert.isTrue(label.classList.contains('editable'));
|
||||
|
||||
assert.equal(label.textContent, 'value text');
|
||||
assert.equal(label.textContent, 'value text');
|
||||
|
||||
MockInteractions.tap(label);
|
||||
MockInteractions.tap(label);
|
||||
|
||||
Polymer.dom.flush();
|
||||
Polymer.dom.flush();
|
||||
|
||||
// The input is visible and the label is hidden:
|
||||
assert.isNull(input.getAttribute('hidden'));
|
||||
assert.isNotNull(label.getAttribute('hidden'));
|
||||
assert.isNull(input.getAttribute('hidden'));
|
||||
assert.isNotNull(label.getAttribute('hidden'));
|
||||
|
||||
assert.equal(input.value, 'value text');
|
||||
assert.equal(input.inputElement.value, 'value text');
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('edit value', done => {
|
||||
const editedStub = sandbox.stub();
|
||||
element.addEventListener('changed', editedStub);
|
||||
Polymer.Base.async(() => {
|
||||
const editedStub = sandbox.stub();
|
||||
element.addEventListener('changed', editedStub);
|
||||
|
||||
MockInteractions.tap(label);
|
||||
MockInteractions.tap(label);
|
||||
|
||||
Polymer.dom.flush();
|
||||
Polymer.dom.flush();
|
||||
|
||||
element._inputText = 'new text';
|
||||
element._inputText = 'new text';
|
||||
|
||||
assert.isFalse(editedStub.called);
|
||||
assert.isFalse(editedStub.called);
|
||||
|
||||
element.async(() => {
|
||||
assert.isTrue(editedStub.called);
|
||||
assert.equal(input.value, 'new text');
|
||||
done();
|
||||
});
|
||||
element.async(() => {
|
||||
assert.isTrue(editedStub.called);
|
||||
assert.equal(input.inputElement.value, 'new text');
|
||||
done();
|
||||
});
|
||||
|
||||
// Press enter:
|
||||
MockInteractions.keyDownOn(input, 13);
|
||||
MockInteractions.keyDownOn(input.inputElement, 13);
|
||||
}, 1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -114,22 +119,25 @@ limitations under the License.
|
||||
setup(() => {
|
||||
element = fixture('read-only');
|
||||
|
||||
input = element.$$('input');
|
||||
input = element.$$('iron-input');
|
||||
label = element.$$('label');
|
||||
});
|
||||
|
||||
test('disallows edit when read-only', () => {
|
||||
test('disallows edit when read-only', done => {
|
||||
Polymer.Base.async(() => {
|
||||
// The input is hidden and the label is visible:
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
|
||||
MockInteractions.tap(label);
|
||||
MockInteractions.tap(label);
|
||||
|
||||
Polymer.dom.flush();
|
||||
Polymer.dom.flush();
|
||||
|
||||
// The input is still hidden and the label is still visible:
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
assert.isNotNull(input.getAttribute('hidden'));
|
||||
assert.isNull(label.getAttribute('hidden'));
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
test('label is not marked as editable', () => {
|
||||
|
||||
@@ -57,10 +57,11 @@ limitations under the License.
|
||||
<div id="topContainer">
|
||||
<div>
|
||||
<label>Filter:</label>
|
||||
<input is="iron-input"
|
||||
type="text"
|
||||
<iron-input
|
||||
id="filter"
|
||||
bind-value="{{filter}}">
|
||||
<input type="text">
|
||||
</iron-input>
|
||||
</div>
|
||||
<div id="createNewContainer"
|
||||
class$="[[_computeCreateClass(createNew)]]">
|
||||
|
||||
@@ -17,4 +17,4 @@ fi
|
||||
|
||||
unzip polygerrit-ui/polygerrit_components.bower_components.zip -d polygerrit-ui/app
|
||||
|
||||
${polylint_bin} --root polygerrit-ui/app --input elements/gr-app.html
|
||||
${polylint_bin} --root polygerrit-ui/app --input elements/gr-app.html --b 'bower_components'
|
||||
|
||||
@@ -97,6 +97,7 @@ limitations under the License.
|
||||
--iron-autogrow-textarea: {
|
||||
border: 1px solid #d1d2d3;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
font-size: 1em;
|
||||
padding: .25em .15em 0 .15em;
|
||||
}
|
||||
@@ -104,7 +105,6 @@ limitations under the License.
|
||||
.gr-form-styles gr-autocomplete {
|
||||
border: none;
|
||||
--gr-autocomplete: {
|
||||
border: 1px solid #d1d2d3;
|
||||
border-radius: 2px;
|
||||
font-size: 1em;
|
||||
height: 2em;
|
||||
|
||||
@@ -32,6 +32,7 @@ limitations under the License.
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
iron-input,
|
||||
input,
|
||||
iron-autogrow-textarea {
|
||||
box-sizing: border-box;
|
||||
|
||||
Reference in New Issue
Block a user