Merge "Offer an option to hide the file comment button"
diff --git a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior.js b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior.js
index b8d54a4..46dfaf2 100644
--- a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior.js
+++ b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior.js
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+import {descendedFromClass} from '../../utils/dom-util.js';
+
export const DomUtilBehavior = {
/**
* Are any ancestors of the element (or the element itself) members of the
@@ -28,13 +30,9 @@
* @return {boolean}
*/
descendedFromClass(element, className, opt_stopElement) {
- let isDescendant = element.classList.contains(className);
- while (!isDescendant && element.parentElement &&
- (!opt_stopElement || element.parentElement !== opt_stopElement)) {
- isDescendant = element.classList.contains(className);
- element = element.parentElement;
- }
- return isDescendant;
+ console.warn('DomUtilBehavior is deprecated.' +
+ 'Use descendedFromClass from utils directly.');
+ return descendedFromClass(element, className, opt_stopElement);
},
};
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
deleted file mode 100644
index d161423..0000000
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @license
- * Copyright (C) 2017 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.
- */
-import '../../../styles/shared-styles.js';
-import '../../shared/gr-button/gr-button.js';
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
-import {PolymerElement} from '@polymer/polymer/polymer-element.js';
-import {htmlTemplate} from './gr-repo-command_html.js';
-
-/** @extends PolymerElement */
-class GrRepoCommand extends GestureEventListeners(
- LegacyElementMixin(
- PolymerElement)) {
- static get template() { return htmlTemplate; }
-
- static get is() { return 'gr-repo-command'; }
-
- static get properties() {
- return {
- title: String,
- disabled: Boolean,
- tooltip: String,
- };
- }
-
- /**
- * Fired when command button is tapped.
- *
- * @event command-tap
- */
-
- _onCommandTap() {
- this.dispatchEvent(
- new CustomEvent('command-tap', {bubbles: true, composed: true}));
- }
-}
-
-customElements.define(GrRepoCommand.is, GrRepoCommand);
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html
deleted file mode 100644
index a73f071..0000000
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 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">
-<meta charset="utf-8">
-<title>gr-repo-command</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
- <template>
- <gr-repo-command></gr-repo-command>
- </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-repo-command.js';
-import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-suite('gr-repo-command tests', () => {
- let element;
-
- setup(() => {
- element = fixture('basic');
- });
-
- test('dispatched command-tap on button tap', done => {
- element.addEventListener('command-tap', () => {
- done();
- });
- MockInteractions.tap(
- dom(element.root).querySelector('gr-button'));
- });
-});
-</script>
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
index 25f656d..4ab1b98 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
@@ -24,7 +24,6 @@
import '../../shared/gr-overlay/gr-overlay.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-create-change-dialog/gr-create-change-dialog.js';
-import '../gr-repo-command/gr-repo-command.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
index 78627a7..d2d6037 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
@@ -104,7 +104,7 @@
}
_computeRequirementIcon(requirementStatus) {
- return requirementStatus ? 'gr-icons:check' : 'gr-icons:hourglass';
+ return requirementStatus ? 'gr-icons:check' : 'gr-icons:schedule';
}
_computeLabels(labelsRecord) {
@@ -132,7 +132,7 @@
_computeLabelIcon(labelInfo) {
if (labelInfo.approved) { return 'gr-icons:check'; }
if (labelInfo.rejected) { return 'gr-icons:close'; }
- return 'gr-icons:hourglass';
+ return 'gr-icons:schedule';
}
/**
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
index e100f91..276e821 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
@@ -51,13 +51,13 @@
assert.equal(element._computeRequirementIcon(true), 'gr-icons:check');
assert.equal(element._computeRequirementIcon(false),
- 'gr-icons:hourglass');
+ 'gr-icons:schedule');
});
test('label computed fields', () => {
assert.equal(element._computeLabelIcon({approved: []}), 'gr-icons:check');
assert.equal(element._computeLabelIcon({rejected: []}), 'gr-icons:close');
- assert.equal(element._computeLabelIcon({}), 'gr-icons:hourglass');
+ assert.equal(element._computeLabelIcon({}), 'gr-icons:schedule');
assert.equal(element._computeLabelClass({approved: []}), 'approved');
assert.equal(element._computeLabelClass({rejected: []}), 'rejected');
@@ -90,7 +90,7 @@
assert.equal(element._requiredLabels.length, 1);
assert.equal(element._optionalLabels[0].label, 'opt_test');
- assert.equal(element._optionalLabels[0].icon, 'gr-icons:hourglass');
+ assert.equal(element._optionalLabels[0].icon, 'gr-icons:schedule');
assert.equal(element._optionalLabels[0].style, '');
assert.ok(element._optionalLabels[0].labelInfo);
});
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index dc207dc..799adde 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -57,7 +57,7 @@
import {RESTClientBehavior} from '../../../behaviors/rest-client-behavior/rest-client-behavior.js';
import {GrEditConstants} from '../../edit/gr-edit-constants.js';
import {GrCountStringFormatter} from '../../shared/gr-count-string-formatter/gr-count-string-formatter.js';
-import {util} from '../../../scripts/util.js';
+import {getComputedStyleValue} from '../../../utils/dom-util.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {pluginEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
@@ -2003,7 +2003,7 @@
_computeShowRelatedToggle() {
// Make sure the max height has been applied, since there is now content
// to populate.
- if (!util.getComputedStyleValue('--relation-chain-max-height', this)) {
+ if (!getComputedStyleValue('--relation-chain-max-height', this)) {
this._updateRelatedChangeMaxHeight();
}
// Prevents showMore from showing when click on related change, since the
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
index 1362fe3..faa81b6 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
@@ -24,7 +24,7 @@
import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
import {GrEditConstants} from '../../edit/gr-edit-constants.js';
import {_testOnly_resetEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
-import {util} from '../../../scripts/util.js';
+import {getComputedStyleValue} from '../../../utils/dom-util.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
@@ -320,7 +320,7 @@
});
const getCustomCssValue =
- cssParam => util.getComputedStyleValue(cssParam, element);
+ cssParam => getComputedStyleValue(cssParam, element);
test('_handleMessageAnchorTap', () => {
element._changeNum = '1';
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 894f0cc..fbae39f 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -1279,6 +1279,14 @@
_renderInOrder(files, diffElements, initialCount) {
let iter = 0;
+ for (const file of files) {
+ const path = file.path;
+ const diffElem = this._findDiffByPath(path, diffElements);
+ if (diffElem) {
+ diffElem.prefetchDiff();
+ }
+ }
+
return (new Promise(resolve => {
this.dispatchEvent(new CustomEvent('reload-drafts', {
detail: {resolve},
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index f93cfe1..ad0d1cf 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -95,6 +95,7 @@
});
stub('gr-diff-host', {
reload() { return Promise.resolve(); },
+ prefetchDiff() {},
});
// Element must be wrapped in an element with direct access to the
@@ -1106,6 +1107,7 @@
reload() {
done();
},
+ prefetchDiff() {},
cancel() {},
getCursorStops() { return []; },
addEventListener(eventName, callback) {
@@ -1163,6 +1165,7 @@
const diffs = [{
path: 'p0',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(callCount++, 2);
return Promise.resolve();
@@ -1170,6 +1173,7 @@
}, {
path: 'p1',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(callCount++, 1);
return Promise.resolve();
@@ -1177,6 +1181,7 @@
}, {
path: 'p2',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(callCount++, 0);
return Promise.resolve();
@@ -1199,6 +1204,7 @@
const diffs = [{
path: 'p0',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(reviewStub.callCount, 2);
assert.equal(callCount++, 2);
@@ -1207,6 +1213,7 @@
}, {
path: 'p1',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(reviewStub.callCount, 1);
assert.equal(callCount++, 1);
@@ -1215,6 +1222,7 @@
}, {
path: 'p2',
style: {},
+ prefetchDiff() {},
reload() {
assert.equal(reviewStub.callCount, 0);
assert.equal(callCount++, 0);
@@ -1237,6 +1245,7 @@
const diffs = [{
path: 'p',
style: {},
+ prefetchDiff() {},
reload() { return Promise.resolve(); },
}];
@@ -1566,6 +1575,7 @@
});
stub('gr-diff-host', {
reload() { return Promise.resolve(); },
+ prefetchDiff() {},
});
// Element must be wrapped in an element with direct access to the
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
index ef11247..cb299de 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
@@ -218,6 +218,11 @@
notify: true,
},
+ _fetchDiffPromise: {
+ type: Object,
+ value: null,
+ },
+
/** @type {?Object} */
_blame: {
type: Object,
@@ -535,8 +540,21 @@
!this.noAutoRender;
}
+ // TODO(milutin): Use rest-api with fetchCacheURL instead of this.
+ prefetchDiff() {
+ if (!!this.changeNum && !!this.patchRange && !!this.path
+ && this._fetchDiffPromise === null) {
+ this._fetchDiffPromise = this._getDiff();
+ }
+ }
+
/** @return {!Promise<!Object>} */
_getDiff() {
+ if (this._fetchDiffPromise !== null) {
+ const fetchDiffPromise = this._fetchDiffPromise;
+ this._fetchDiffPromise = null;
+ return fetchDiffPromise;
+ }
// Wrap the diff request in a new promise so that the error handler
// rejects the promise, allowing the error to be handled in the .catch.
return new Promise((resolve, reject) => {
@@ -793,6 +811,7 @@
}
threadEl.changeNum = this.changeNum;
threadEl.patchNum = thread.patchNum;
+ threadEl.showPatchset = false;
threadEl.lineNum = thread.lineNum;
const rootIdChangedListener = changeEvent => {
thread.rootId = changeEvent.detail.value;
@@ -906,6 +925,7 @@
return;
}
+ this._fetchDiffPromise = null;
if (preferredWhitespaceLevel !== loadedWhitespaceLevel &&
!noRenderOnPrefsChange) {
this.reload();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
index b8f26b2..342c7ec 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
@@ -445,6 +445,19 @@
});
});
+ test('prefetch getDiff', done => {
+ const diffRestApiStub = sandbox.stub(element.$.restAPI, 'getDiff')
+ .returns(Promise.resolve({content: []}));
+ element.changeNum = 123;
+ element.patchRange = {basePatchNum: 1, patchNum: 2};
+ element.path = 'file.txt';
+ element.prefetchDiff();
+ element._getDiff().then(() =>{
+ assert.isTrue(diffRestApiStub.calledOnce);
+ done();
+ });
+ });
+
test('_getDiff handles null diff responses', done => {
stub('gr-rest-api-interface', {
getDiff() { return Promise.resolve(null); },
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
index 608e898..cfbe481 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
@@ -24,7 +24,7 @@
import {htmlTemplate} from './gr-diff-selection_html.js';
import {DomUtilBehavior} from '../../../behaviors/dom-util-behavior/dom-util-behavior.js';
import {GrRangeNormalizer} from '../gr-diff-highlight/gr-range-normalizer.js';
-import {util} from '../../../scripts/util.js';
+import {querySelectorAll} from '../../../utils/dom-util.js';
/**
* Possible CSS classes indicating the state of selection. Dynamically added/
@@ -203,7 +203,7 @@
}
_getSelection() {
- const diffHosts = util.querySelectorAll(document.body, 'gr-diff');
+ const diffHosts = querySelectorAll(document.body, 'gr-diff');
if (!diffHosts.length) return window.getSelection();
const curDiffHost = diffHosts.find(diffHost => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.js
index d497b9a..a10db97 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.js
@@ -21,7 +21,7 @@
import './gr-diff.js';
import {dom, flush} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {GrDiffBuilderImage} from '../gr-diff-builder/gr-diff-builder-image.js';
-import {util} from '../../../scripts/util.js';
+import {getComputedStyleValue} from '../../../utils/dom-util.js';
import {_setHiddenScroll} from '../../../scripts/hiddenscroll.js';
import {runA11yAudit} from '../../../test/a11y-test-utils.js';
import '@polymer/paper-button/paper-button.js';
@@ -82,14 +82,14 @@
element = basicFixture.instantiate();
element.prefs = Object.assign({}, MINIMAL_PREFS, {line_wrapping: true});
flushAsynchronousOperations();
- assert.equal(util.getComputedStyleValue('--line-limit', element), '80ch');
+ assert.equal(getComputedStyleValue('--line-limit', element), '80ch');
});
test('line limit without line_wrapping', () => {
element = basicFixture.instantiate();
element.prefs = Object.assign({}, MINIMAL_PREFS, {line_wrapping: false});
flushAsynchronousOperations();
- assert.isNotOk(util.getComputedStyleValue('--line-limit', element));
+ assert.isNotOk(getComputedStyleValue('--line-limit', element));
});
suite('_get{PatchNum|IsParentComment}ByLineAndContent', () => {
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.js b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.js
index 752570f..1a2cd28 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.js
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.js
@@ -14,20 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import '../../admin/gr-repo-command/gr-repo-command.js';
-import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
-import {html} from '@polymer/polymer/lib/utils/html-tag.js';
-Polymer({
- _template: html`
- <gr-repo-command title="[[title]]">
- </gr-repo-command>
-`,
+import {PolymerElement} from '@polymer/polymer/polymer-element.js';
+import {htmlTemplate} from './gr-plugin-repo-command_html.js';
- is: 'gr-plugin-repo-command',
+class GrPluginRepoCommand extends PolymerElement {
+ static get is() {
+ return 'gr-plugin-repo-command';
+ }
- properties: {
- title: String,
- repoName: String,
- config: Object,
- },
-});
+ static get properties() {
+ return {
+ title: String,
+ repoName: String,
+ config: Object,
+ };
+ }
+
+ static get template() {
+ return htmlTemplate;
+ }
+
+ _handleClick() {
+ this.dispatchEvent(
+ new CustomEvent('command-tap', {composed: true, bubbles: true})
+ );
+ }
+}
+
+customElements.define(GrPluginRepoCommand.is, GrPluginRepoCommand);
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_html.js b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command_html.js
similarity index 83%
rename from polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_html.js
rename to polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command_html.js
index 50aca6d..1e5088b3 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_html.js
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command_html.js
@@ -23,12 +23,6 @@
margin-bottom: var(--spacing-xxl);
}
</style>
- <h3 class="heading-3">[[title]]</h3>
- <gr-button
- title$="[[tooltip]]"
- disabled$="[[disabled]]"
- on-click="_onCommandTap"
- >
- [[title]]
- </gr-button>
+ <h3>[[title]]</h3>
+ <gr-button on-click="_handleClick">[[title]]</gr-button>
`;
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
index 32ae959..1af91fd 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
@@ -73,13 +73,12 @@
const pluginCommand = element.shadowRoot
.querySelector('gr-plugin-repo-command');
assert.isOk(pluginCommand);
- const command = pluginCommand.shadowRoot
- .querySelector('gr-repo-command');
- assert.isOk(command);
- assert.equal(command.title, 'foo');
+ const btn = pluginCommand.shadowRoot
+ .querySelector('gr-button');
+ assert.isOk(btn);
+ assert.equal(btn.textContent, 'foo');
assert.isFalse(tapStub.called);
- MockInteractions.tap(command.shadowRoot
- .querySelector('gr-button'));
+ MockInteractions.tap(btn);
assert.isTrue(tapStub.called);
done();
});
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
index bdac50f..346d84e 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
@@ -23,7 +23,7 @@
import {htmlTemplate} from './gr-button_html.js';
import {TooltipBehavior} from '../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js';
import {KeyboardShortcutBehavior} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
-import {util} from '../../../scripts/util.js';
+import {getEventPath} from '../../../utils/dom-util.js';
import {appContext} from '../../../services/app-context.js';
/**
@@ -113,7 +113,7 @@
}
this.reporting.reportInteraction('button-click',
- {path: util.getEventPath(e)});
+ {path: getEventPath(e)});
}
_disabledChanged(disabled) {
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
index 7d5d170..fa686da 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
@@ -159,6 +159,10 @@
type: Boolean,
value: true,
},
+ showPatchset: {
+ type: Boolean,
+ value: true,
+ },
};
}
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.js b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.js
index 2bb5b66ea..837a58f 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.js
@@ -116,6 +116,7 @@
patch-num="[[patchNum]]"
draft="[[_isDraft(comment)]]"
show-actions="[[_showActions]]"
+ show-patchset="[[showPatchset]]"
comment-side="[[comment.__commentSide]]"
side="[[comment.side]]"
project-config="[[_projectConfig]]"
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
index 6697880..02fec5a 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
@@ -213,6 +213,10 @@
type: Boolean,
value: false,
},
+ showPatchset: {
+ type: Boolean,
+ value: true,
+ },
_respectfulReviewTip: String,
_respectfulTipDismissed: {
type: Boolean,
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.js
index aece8ad..1d04969 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.js
@@ -231,6 +231,10 @@
.pointer {
cursor: pointer;
}
+ .patchset-text {
+ color: var(--deemphasized-text-color);
+ margin-left: var(--spacing-s);
+ }
</style>
<div id="container" class="container">
<div class="header" id="header" on-click="_handleToggleCollapsed">
@@ -269,7 +273,9 @@
>
<iron-icon id="icon" icon="gr-icons:delete"></iron-icon>
</gr-button>
- <span> Patchset [[patchNum]]</span>
+ <template is="dom-if" if="[[showPatchset]]">
+ <span class="patchset-text"> Patchset [[patchNum]]</span>
+ </template>
<span class="separator"></span>
<span class="date" tabindex="0" on-click="_handleAnchorClick">
<gr-date-formatter
diff --git a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.js b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.js
index 85caa61..070ac02 100644
--- a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.js
+++ b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.js
@@ -102,6 +102,8 @@
<g id="pets"><circle cx="4.5" cy="9.5" r="2.5"/><circle cx="9" cy="5.5" r="2.5"/><circle cx="15" cy="5.5" r="2.5"/><circle cx="19.5" cy="9.5" r="2.5"/><path d="M17.34 14.86c-.87-1.02-1.6-1.89-2.48-2.91-.46-.54-1.05-1.08-1.75-1.32-.11-.04-.22-.07-.33-.09-.25-.04-.52-.04-.78-.04s-.53 0-.79.05c-.11.02-.22.05-.33.09-.7.24-1.28.78-1.75 1.32-.87 1.02-1.6 1.89-2.48 2.91-1.31 1.31-2.92 2.76-2.62 4.79.29 1.02 1.02 2.03 2.33 2.32.73.15 3.06-.44 5.54-.44h.18c2.48 0 4.81.58 5.54.44 1.31-.29 2.04-1.31 2.33-2.32.31-2.04-1.3-3.49-2.61-4.8z"/><path d="M0 0h24v24H0z" fill="none"/></g>
<!-- This SVG is a copy from material.io https://material.io/icons/#visibility-->
<g id="ready"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></g>
+ <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons -->
+ <g id="schedule"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></g>
</defs>
</svg>
</iron-iconset-svg>`;
diff --git a/polygerrit-ui/app/embed/gr-diff-app-context-init.js b/polygerrit-ui/app/embed/gr-diff-app-context-init.js
index 8a7fb66..90110f0 100644
--- a/polygerrit-ui/app/embed/gr-diff-app-context-init.js
+++ b/polygerrit-ui/app/embed/gr-diff-app-context-init.js
@@ -24,7 +24,7 @@
}
/**
- * @returns {string[]} array of all enabled experiments.
+ * @returns {!Array<string>} array of all enabled experiments.
*/
get enabledExperiments() {
return [];
diff --git a/polygerrit-ui/app/scripts/util.js b/polygerrit-ui/app/scripts/util.js
index 0103bf2..e4be858 100644
--- a/polygerrit-ui/app/scripts/util.js
+++ b/polygerrit-ui/app/scripts/util.js
@@ -15,17 +15,6 @@
* limitations under the License.
*/
-function getPathFromNode(el) {
- if (!el.tagName || el.tagName === 'GR-APP'
- || el instanceof DocumentFragment
- || el instanceof HTMLSlotElement) {
- return '';
- }
- let path = el.tagName.toLowerCase();
- if (el.id) path += `#${el.id}`;
- if (el.className) path += `.${el.className.replace(/ /g, '.')}`;
- return path;
-}
// TODO (dmfilippov): Each function must be exported separately. According to
// the code style guide, a namespacing is not allowed.
export const util = {
@@ -76,133 +65,4 @@
};
return wrappedPromise;
},
-
- /**
- * Get computed style value.
- *
- * If ShadyCSS is provided, use ShadyCSS api.
- * If `getComputedStyleValue` is provided on the element, use it.
- * Otherwise fallback to native method (in polymer 2).
- *
- */
- getComputedStyleValue: (name, el) => {
- let style;
- if (window.ShadyCSS) {
- style = ShadyCSS.getComputedStyleValue(el, name);
- } else if (el.getComputedStyleValue) {
- style = el.getComputedStyleValue(name);
- } else {
- style = getComputedStyle(el).getPropertyValue(name);
- }
- return style;
- },
-
- /**
- * Query selector on a dom element.
- *
- * This is shadow DOM compatible, but only works when selector is within
- * one shadow host, won't work if your selector is crossing
- * multiple shadow hosts.
- *
- */
- querySelector: (el, selector) => {
- let nodes = [el];
- let result = null;
- while (nodes.length) {
- const node = nodes.pop();
-
- // Skip if it's an invalid node.
- if (!node || !node.querySelector) continue;
-
- // Try find it with native querySelector directly
- result = node.querySelector(selector);
-
- if (result) {
- break;
- }
-
- // Add all nodes with shadowRoot and loop through
- const allShadowNodes = [...node.querySelectorAll('*')]
- .filter(child => !!child.shadowRoot)
- .map(child => child.shadowRoot);
- nodes = nodes.concat(allShadowNodes);
-
- // Add shadowRoot of current node if has one
- // as its not included in node.querySelectorAll('*')
- if (node.shadowRoot) {
- nodes.push(node.shadowRoot);
- }
- }
- return result;
- },
-
- /**
- * Query selector all dom elements matching with certain selector.
- *
- * This is shadow DOM compatible, but only works when selector is within
- * one shadow host, won't work if your selector is crossing
- * multiple shadow hosts.
- *
- * Note: this can be very expensive, only use when have to.
- */
- querySelectorAll: (el, selector) => {
- let nodes = [el];
- const results = new Set();
- while (nodes.length) {
- const node = nodes.pop();
-
- if (!node || !node.querySelectorAll) continue;
-
- // Try find all from regular children
- [...node.querySelectorAll(selector)]
- .forEach(el => results.add(el));
-
- // Add all nodes with shadowRoot and loop through
- const allShadowNodes = [...node.querySelectorAll('*')]
- .filter(child => !!child.shadowRoot)
- .map(child => child.shadowRoot);
- nodes = nodes.concat(allShadowNodes);
-
- // Add shadowRoot of current node if has one
- // as its not included in node.querySelectorAll('*')
- if (node.shadowRoot) {
- nodes.push(node.shadowRoot);
- }
- }
- return [...results];
- },
-
- /**
- * Retrieves the dom path of the current event.
- *
- * If the event object contains a `path` property, then use it,
- * otherwise, construct the dom path based on the event target.
- *
- * @param {!Event} e
- * @return {string}
- * @example
- *
- * domNode.onclick = e => {
- * getEventPath(e); // eg: div.class1>p#pid.class2
- * }
- */
- getEventPath: e => {
- if (!e) return '';
-
- let path = e.path;
- if (!path || !path.length) {
- path = [];
- let el = e.target;
- while (el) {
- path.push(el);
- el = el.parentNode || el.host;
- }
- }
-
- return path.reduce((domPath, curEl) => {
- const pathForEl = getPathFromNode(curEl);
- if (!pathForEl) return domPath;
- return domPath ? `${pathForEl}>${domPath}` : pathForEl;
- }, '');
- },
};
diff --git a/polygerrit-ui/app/scripts/util_test.html b/polygerrit-ui/app/scripts/util_test.html
deleted file mode 100644
index a3893d2..0000000
--- a/polygerrit-ui/app/scripts/util_test.html
+++ /dev/null
@@ -1,89 +0,0 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 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">
-<meta charset="utf-8">
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
- <template>
- <div id="test" class="a b c">
- <a class="testBtn"></a>
- </div>
- </template>
-</test-fixture>
-
-<script type="module">
- import '../test/common-test-setup.js';
- import {util} from './util.js';
- suite('util tests', () => {
- suite('getEventPath', () => {
- test('empty event', () => {
- assert.equal(util.getEventPath(), '');
- assert.equal(util.getEventPath(null), '');
- assert.equal(util.getEventPath(undefined), '');
- assert.equal(util.getEventPath({}), '');
- });
-
- test('event with fake path', () => {
- assert.equal(util.getEventPath({path: []}), '');
- assert.equal(util.getEventPath({path: [
- {tagName: 'dd'},
- ]}), 'dd');
- });
-
- test('event with fake complicated path', () => {
- assert.equal(util.getEventPath({path: [
- {tagName: 'dd', id: 'test', className: 'a b'},
- {tagName: 'DIV', id: 'test2', className: 'a b c'},
- ]}), 'div#test2.a.b.c>dd#test.a.b');
- });
-
- test('event with fake target', () => {
- const fakeTargetParent2 = {
- tagName: 'DIV', id: 'test2', className: 'a b c',
- };
- const fakeTargetParent1 = {
- parentNode: fakeTargetParent2,
- tagName: 'dd',
- id: 'test',
- className: 'a b',
- };
- const fakeTarget = {tagName: 'SPAN', parentNode: fakeTargetParent1};
- assert.equal(
- util.getEventPath({target: fakeTarget}),
- 'div#test2.a.b.c>dd#test.a.b>span'
- );
- });
-
- test('event with real click', () => {
- const element = fixture('basic');
- const aLink = element.querySelector('a');
- let path;
- aLink.onclick = e => path = util.getEventPath(e);
- MockInteractions.click(aLink);
- assert.equal(
- path,
- 'html>body>test-fixture#basic>div#test.a.b.c>a.testBtn'
- );
- });
- });
- });
-</script>
diff --git a/polygerrit-ui/app/test/tests.js b/polygerrit-ui/app/test/tests.js
index ad54fc3..f095302 100644
--- a/polygerrit-ui/app/test/tests.js
+++ b/polygerrit-ui/app/test/tests.js
@@ -41,7 +41,6 @@
'admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.html',
'admin/gr-plugin-list/gr-plugin-list_test.html',
'admin/gr-repo-access/gr-repo-access_test.html',
- 'admin/gr-repo-command/gr-repo-command_test.html',
'admin/gr-repo-commands/gr-repo-commands_test.html',
'admin/gr-repo-dashboards/gr-repo-dashboards_test.html',
'admin/gr-repo-detail-list/gr-repo-detail-list_test.html',
@@ -245,7 +244,6 @@
'gr-group-suggestions-provider/gr-group-suggestions-provider_test.html',
'gr-display-name-utils/gr-display-name-utils_test.html',
'gr-email-suggestions-provider/gr-email-suggestions-provider_test.html',
- 'util_test.html',
];
/* eslint-enable max-len */
for (let file of scripts) {
diff --git a/polygerrit-ui/app/utils/dom-util.js b/polygerrit-ui/app/utils/dom-util.js
new file mode 100644
index 0000000..a9f080f
--- /dev/null
+++ b/polygerrit-ui/app/utils/dom-util.js
@@ -0,0 +1,178 @@
+/**
+ * @license
+ * Copyright (C) 2020 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 getPathFromNode(el) {
+ if (!el.tagName || el.tagName === 'GR-APP'
+ || el instanceof DocumentFragment
+ || el instanceof HTMLSlotElement) {
+ return '';
+ }
+ let path = el.tagName.toLowerCase();
+ if (el.id) path += `#${el.id}`;
+ if (el.className) path += `.${el.className.replace(/ /g, '.')}`;
+ return path;
+}
+
+/**
+ * Get computed style value.
+ *
+ * If ShadyCSS is provided, use ShadyCSS api.
+ * If `getComputedStyleValue` is provided on the element, use it.
+ * Otherwise fallback to native method (in polymer 2).
+ *
+ */
+export function getComputedStyleValue(name, el) {
+ let style;
+ if (window.ShadyCSS) {
+ style = ShadyCSS.getComputedStyleValue(el, name);
+ } else if (el.getComputedStyleValue) {
+ style = el.getComputedStyleValue(name);
+ } else {
+ style = getComputedStyle(el).getPropertyValue(name);
+ }
+ return style;
+}
+
+/**
+ * Query selector on a dom element.
+ *
+ * This is shadow DOM compatible, but only works when selector is within
+ * one shadow host, won't work if your selector is crossing
+ * multiple shadow hosts.
+ *
+ */
+export function querySelector(el, selector) {
+ let nodes = [el];
+ let result = null;
+ while (nodes.length) {
+ const node = nodes.pop();
+
+ // Skip if it's an invalid node.
+ if (!node || !node.querySelector) continue;
+
+ // Try find it with native querySelector directly
+ result = node.querySelector(selector);
+
+ if (result) {
+ break;
+ }
+
+ // Add all nodes with shadowRoot and loop through
+ const allShadowNodes = [...node.querySelectorAll('*')]
+ .filter(child => !!child.shadowRoot)
+ .map(child => child.shadowRoot);
+ nodes = nodes.concat(allShadowNodes);
+
+ // Add shadowRoot of current node if has one
+ // as its not included in node.querySelectorAll('*')
+ if (node.shadowRoot) {
+ nodes.push(node.shadowRoot);
+ }
+ }
+ return result;
+}
+
+/**
+ * Query selector all dom elements matching with certain selector.
+ *
+ * This is shadow DOM compatible, but only works when selector is within
+ * one shadow host, won't work if your selector is crossing
+ * multiple shadow hosts.
+ *
+ * Note: this can be very expensive, only use when have to.
+ */
+export function querySelectorAll(el, selector) {
+ let nodes = [el];
+ const results = new Set();
+ while (nodes.length) {
+ const node = nodes.pop();
+
+ if (!node || !node.querySelectorAll) continue;
+
+ // Try find all from regular children
+ [...node.querySelectorAll(selector)]
+ .forEach(el => results.add(el));
+
+ // Add all nodes with shadowRoot and loop through
+ const allShadowNodes = [...node.querySelectorAll('*')]
+ .filter(child => !!child.shadowRoot)
+ .map(child => child.shadowRoot);
+ nodes = nodes.concat(allShadowNodes);
+
+ // Add shadowRoot of current node if has one
+ // as its not included in node.querySelectorAll('*')
+ if (node.shadowRoot) {
+ nodes.push(node.shadowRoot);
+ }
+ }
+ return [...results];
+}
+
+/**
+ * Retrieves the dom path of the current event.
+ *
+ * If the event object contains a `path` property, then use it,
+ * otherwise, construct the dom path based on the event target.
+ *
+ * @param {!Event} e
+ * @return {string}
+ * @example
+ *
+ * domNode.onclick = e => {
+ * getEventPath(e); // eg: div.class1>p#pid.class2
+ * }
+ */
+export function getEventPath(e) {
+ if (!e) return '';
+
+ let path = e.path;
+ if (!path || !path.length) {
+ path = [];
+ let el = e.target;
+ while (el) {
+ path.push(el);
+ el = el.parentNode || el.host;
+ }
+ }
+
+ return path.reduce((domPath, curEl) => {
+ const pathForEl = getPathFromNode(curEl);
+ if (!pathForEl) return domPath;
+ return domPath ? `${pathForEl}>${domPath}` : pathForEl;
+ }, '');
+}
+
+/**
+ * Are any ancestors of the element (or the element itself) members of the
+ * given class.
+ *
+ * @param {!Element} element
+ * @param {string} className
+ * @param {Element=} opt_stopElement If provided, stop traversing the
+ * ancestry when the stop element is reached. The stop element's class
+ * is not checked.
+ * @return {boolean}
+ */
+export function descendedFromClass(element, className, opt_stopElement) {
+ let isDescendant = element.classList.contains(className);
+ while (!isDescendant && element.parentElement &&
+ (!opt_stopElement || element.parentElement !== opt_stopElement)) {
+ isDescendant = element.classList.contains(className);
+ element = element.parentElement;
+ }
+ return isDescendant;
+}
\ No newline at end of file
diff --git a/polygerrit-ui/app/utils/dom-util_test.js b/polygerrit-ui/app/utils/dom-util_test.js
new file mode 100644
index 0000000..c317578
--- /dev/null
+++ b/polygerrit-ui/app/utils/dom-util_test.js
@@ -0,0 +1,139 @@
+/**
+ * @license
+ * Copyright (C) 2020 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.
+ */
+import '../test/common-test-setup-karma.js';
+import {getComputedStyleValue, querySelector, querySelectorAll, descendedFromClass, getEventPath} from './dom-util.js';
+import {PolymerElement} from '@polymer/polymer/polymer-element.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+class TestEle extends PolymerElement {
+ static get is() {
+ return 'dom-util-test-element';
+ }
+
+ static get template() {
+ return html`
+ <div>
+ <div class="a">
+ <div class="b">
+ <div class="c"></div>
+ </div>
+ <span class="ss"></span>
+ </div>
+ <span class="ss"></span>
+ </div>
+ `;
+ }
+}
+
+customElements.define(TestEle.is, TestEle);
+
+const basicFixture = fixtureFromTemplate(html`
+ <div id="test" class="a b c">
+ <a class="testBtn" style="color:red;"></a>
+ <dom-util-test-element></dom-util-test-element>
+ <span class="ss"></span>
+ </div>
+`);
+
+suite('dom-util tests', () => {
+ suite('getEventPath', () => {
+ test('empty event', () => {
+ assert.equal(getEventPath(), '');
+ assert.equal(getEventPath(null), '');
+ assert.equal(getEventPath(undefined), '');
+ assert.equal(getEventPath({}), '');
+ });
+
+ test('event with fake path', () => {
+ assert.equal(getEventPath({path: []}), '');
+ assert.equal(getEventPath({path: [
+ {tagName: 'dd'},
+ ]}), 'dd');
+ });
+
+ test('event with fake complicated path', () => {
+ assert.equal(getEventPath({path: [
+ {tagName: 'dd', id: 'test', className: 'a b'},
+ {tagName: 'DIV', id: 'test2', className: 'a b c'},
+ ]}), 'div#test2.a.b.c>dd#test.a.b');
+ });
+
+ test('event with fake target', () => {
+ const fakeTargetParent2 = {
+ tagName: 'DIV', id: 'test2', className: 'a b c',
+ };
+ const fakeTargetParent1 = {
+ parentNode: fakeTargetParent2,
+ tagName: 'dd',
+ id: 'test',
+ className: 'a b',
+ };
+ const fakeTarget = {tagName: 'SPAN', parentNode: fakeTargetParent1};
+ assert.equal(
+ getEventPath({target: fakeTarget}),
+ 'div#test2.a.b.c>dd#test.a.b>span'
+ );
+ });
+
+ test('event with real click', () => {
+ const element = basicFixture.instantiate();
+ const aLink = element.querySelector('a');
+ let path;
+ aLink.onclick = e => path = getEventPath(e);
+ MockInteractions.click(aLink);
+ assert.equal(
+ path,
+ `html>body>test-fixture#${basicFixture.fixtureId}>` +
+ 'div#test.a.b.c>a.testBtn'
+ );
+ });
+ });
+
+ suite('querySelector and querySelectorAll', () => {
+ test('query cross shadow dom', () => {
+ const element = basicFixture.instantiate();
+ const theFirstEl = querySelector(element, '.ss');
+ const allEls = querySelectorAll(element, '.ss');
+ assert.equal(allEls.length, 3);
+ assert.equal(theFirstEl, allEls[0]);
+ });
+ });
+
+ suite('getComputedStyleValue', () => {
+ test('color style', () => {
+ const element = basicFixture.instantiate();
+ const testBtn = querySelector(element, '.testBtn');
+ assert.equal(
+ getComputedStyleValue('color', testBtn), 'rgb(255, 0, 0)'
+ );
+ });
+ });
+
+ suite('descendedFromClass', () => {
+ test('basic tests', () => {
+ const element = basicFixture.instantiate();
+ const testEl = querySelector(element, 'dom-util-test-element');
+ // .c is a child of .a and not vice versa.
+ assert.isTrue(descendedFromClass(querySelector(testEl, '.c'), 'a'));
+ assert.isFalse(descendedFromClass(querySelector(testEl, '.a'), 'c'));
+
+ // Stops at stop element.
+ assert.isFalse(descendedFromClass(querySelector(testEl, '.c'), 'a',
+ querySelector(testEl, '.b')));
+ });
+ });
+});
\ No newline at end of file