Convert GrStorage from a Polymer element to a class
Change-Id: I4b1d7da81d07d34d3a216188c656e59d5ad4f826
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
index ec985af..23718fa 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
@@ -734,7 +734,6 @@
on-reload-diff-preference="_handleReloadingDiffPreference"
>
</gr-diff-preferences-dialog>
- <gr-storage id="storage"></gr-storage>
<gr-diff-cursor id="diffCursor"></gr-diff-cursor>
<gr-cursor-manager
id="fileCursor"
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index a0906de..253b5ff 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -168,7 +168,6 @@
labelScores: GrLabelScores;
textarea: GrTextarea;
reviewerConfirmationOverlay: GrOverlay;
- storage: GrStorage;
};
}
@@ -376,6 +375,8 @@
private readonly restApiService = appContext.restApiService;
+ private readonly storage = new GrStorage();
+
get keyBindings() {
return {
esc: '_handleEscKey',
@@ -1317,7 +1318,7 @@
}
_loadStoredDraft() {
- const draft = this.$.storage.getDraftComment(this._getStorageLocation());
+ const draft = this.storage.getDraftComment(this._getStorageLocation());
return draft?.message ?? '';
}
@@ -1336,12 +1337,9 @@
if (!newDraft.length && oldDraft) {
// If the draft has been modified to be empty, then erase the storage
// entry.
- this.$.storage.eraseDraftComment(this._getStorageLocation());
+ this.storage.eraseDraftComment(this._getStorageLocation());
} else if (newDraft.length) {
- this.$.storage.setDraftComment(
- this._getStorageLocation(),
- this.draft
- );
+ this.storage.setDraftComment(this._getStorageLocation(), this.draft);
}
},
STORAGE_DEBOUNCE_INTERVAL_MS
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_html.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_html.ts
index 2fca13d..5409243 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_html.ts
@@ -613,5 +613,4 @@
</div>
</div>
<gr-js-api-interface id="jsAPI"></gr-js-api-interface>
- <gr-storage id="storage"></gr-storage>
`;
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
index e38742a..4547e53 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
@@ -114,10 +114,9 @@
],
};
- getDraftCommentStub = sinon.stub(element.$.storage, 'getDraftComment');
- setDraftCommentStub = sinon.stub(element.$.storage, 'setDraftComment');
- eraseDraftCommentStub = sinon.stub(element.$.storage,
- 'eraseDraftComment');
+ getDraftCommentStub = sinon.stub(element.storage, 'getDraftComment');
+ setDraftCommentStub = sinon.stub(element.storage, 'setDraftComment');
+ eraseDraftCommentStub = sinon.stub(element.storage, 'eraseDraftComment');
// sinon.stub(patchSetUtilMockProxy, 'fetchChangeUpdates')
// .returns(Promise.resolve({isLatest: true}));
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_html.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_html.ts
index 4f57c50..a00927c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_html.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_html.ts
@@ -425,7 +425,6 @@
on-reload-diff-preference="_handleReloadingDiffPreference"
>
</gr-diff-preferences-dialog>
- <gr-storage id="storage"></gr-storage>
<gr-diff-cursor
id="cursor"
on-navigate-to-next-unreviewed-file="_handleNextUnreviewedFile"
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
index 4be8edf..047abe3 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
@@ -55,11 +55,6 @@
const STORAGE_DEBOUNCE_INTERVAL_MS = 100;
-export interface GrEditorView {
- $: {
- storage: GrStorage;
- };
-}
@customElement('gr-editor-view')
export class GrEditorView extends KeyboardShortcutMixin(
GestureEventListeners(LegacyElementMixin(PolymerElement))
@@ -124,6 +119,8 @@
private readonly restApiService = appContext.restApiService;
+ private readonly storage = new GrStorage();
+
reporting = appContext.reportingService;
get keyBindings() {
@@ -237,9 +234,7 @@
if (patchNum === undefined) {
return Promise.reject(new Error('patchNum undefined'));
}
- const storedContent = this.$.storage.getEditableContentItem(
- this.storageKey
- );
+ const storedContent = this.storage.getEditableContentItem(this.storageKey);
return this.restApiService
.getFileContent(changeNum, path, patchNum)
@@ -275,7 +270,7 @@
}
this._saving = true;
this._showAlert(SAVING_MESSAGE);
- this.$.storage.eraseEditableContentItem(this.storageKey);
+ this.storage.eraseEditableContentItem(this.storageKey);
if (!this._newContent)
return Promise.reject(new Error('new content undefined'));
return this.restApiService
@@ -359,9 +354,9 @@
const content = e.detail.value;
if (content) {
this.set('_newContent', e.detail.value);
- this.$.storage.setEditableContentItem(this.storageKey, content);
+ this.storage.setEditableContentItem(this.storageKey, content);
} else {
- this.$.storage.eraseEditableContentItem(this.storageKey);
+ this.storage.eraseEditableContentItem(this.storageKey);
}
},
STORAGE_DEBOUNCE_INTERVAL_MS
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_html.ts b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_html.ts
index 0b03856..0df04cb 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_html.ts
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_html.ts
@@ -133,5 +133,4 @@
></gr-default-editor>
</gr-endpoint-decorator>
</div>
- <gr-storage id="storage"></gr-storage>
`;
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
index 03e0b4c..10f7921 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
@@ -103,7 +103,7 @@
});
test('reacts to content-change event', () => {
- const storeStub = sinon.spy(element.$.storage, 'setEditableContentItem');
+ const storeStub = sinon.spy(element.storage, 'setEditableContentItem');
element._newContent = 'test';
element.$.editorEndpoint.dispatchEvent(new CustomEvent('content-change', {
bubbles: true, composed: true,
@@ -136,7 +136,7 @@
test('file modification and save, !ok response', () => {
const saveSpy = sinon.spy(element, '_saveEdit');
- const eraseStub = sinon.stub(element.$.storage,
+ const eraseStub = sinon.stub(element.storage,
'eraseEditableContentItem');
const alertStub = sinon.stub(element, '_showAlert');
saveFileStub.returns(Promise.resolve({ok: false}));
@@ -248,7 +248,7 @@
element._newContent = 'initial';
element._content = 'initial';
element._type = 'initial';
- sinon.stub(element.$.storage, 'getEditableContentItem').returns(null);
+ sinon.stub(element.storage, 'getEditableContentItem').returns(null);
});
test('res.ok', () => {
@@ -377,7 +377,7 @@
suite('gr-storage caching', () => {
test('local edit exists', () => {
- sinon.stub(element.$.storage, 'getEditableContentItem')
+ sinon.stub(element.storage, 'getEditableContentItem')
.returns({message: 'pending edit'});
stubRestApi('getFileContent')
.returns(Promise.resolve({
@@ -400,7 +400,7 @@
});
test('local edit exists, is same as remote edit', () => {
- sinon.stub(element.$.storage, 'getEditableContentItem')
+ sinon.stub(element.storage, 'getEditableContentItem')
.returns({message: 'pending edit'});
stubRestApi('getFileContent')
.returns(Promise.resolve({
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index dd48556..c8b3be2 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -56,7 +56,6 @@
export interface GrCommentThread {
$: {
- storage: GrStorage;
replyBtn: GrButton;
quoteBtn: GrButton;
};
@@ -187,6 +186,8 @@
flagsService = appContext.flagsService;
+ readonly storage = new GrStorage();
+
readonly restApiService = appContext.restApiService;
/** @override */
@@ -575,7 +576,7 @@
path: changeComment.path,
line: changeComment.line,
};
- this.$.storage.setDraftComment(
+ this.storage.setDraftComment(
commentLocation,
changeComment.message ?? ''
);
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
index dd9f9e8..ba541be 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
@@ -167,5 +167,4 @@
</div>
</div>
</div>
- <gr-storage id="storage"></gr-storage>
`;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
index b70a55a..e1c6bff 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
@@ -652,7 +652,7 @@
__draft: true,
},
];
- const storageStub = sinon.stub(element.$.storage, 'setDraftComment');
+ const storageStub = sinon.stub(element.storage, 'setDraftComment');
flush();
const draftEl = element.root?.querySelectorAll('gr-comment')[1];
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
index 644b0ae..5d5f4f3 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -95,7 +95,6 @@
export interface GrComment {
$: {
- storage: GrStorage;
container: HTMLDivElement;
resolvedCheckbox: HTMLInputElement;
};
@@ -271,6 +270,8 @@
private readonly restApiService = appContext.restApiService;
+ private readonly storage = new GrStorage();
+
reporting = appContext.reportingService;
/** @override */
@@ -332,7 +333,7 @@
if (!editing) return;
// visibility based on cache this will make sure we only and always show
// a tip once every Math.max(a day, period between creating comments)
- const cachedVisibilityOfRespectfulTip = this.$.storage.getRespectfulTipVisibility();
+ const cachedVisibilityOfRespectfulTip = this.storage.getRespectfulTipVisibility();
if (!cachedVisibilityOfRespectfulTip) {
// we still want to show the tip with a probability of 30%
if (this.getRandomNum(0, 3) >= 1) return;
@@ -343,7 +344,7 @@
tip: this._respectfulReviewTip,
});
// update cache
- this.$.storage.setRespectfulTipVisibility();
+ this.storage.setRespectfulTipVisibility();
}
}
@@ -362,7 +363,7 @@
tip: this._respectfulReviewTip,
});
// add a 14-day delay to the tip cache
- this.$.storage.setRespectfulTipVisibility(/* delayDays= */ 14);
+ this.storage.setRespectfulTipVisibility(/* delayDays= */ 14);
}
_onRespectfulReadMoreClick() {
@@ -491,7 +492,7 @@
if (this.changeNum === undefined) {
throw new Error('undefined changeNum');
}
- this.$.storage.eraseDraftComment({
+ this.storage.eraseDraftComment({
changeNum: this.changeNum,
patchNum: this._getPatchNum(),
path: this.comment.path,
@@ -663,9 +664,9 @@
if ((!message || !message.length) && oldValue) {
// If the draft has been modified to be empty, then erase the storage
// entry.
- this.$.storage.eraseDraftComment(commentLocation);
+ this.storage.eraseDraftComment(commentLocation);
} else {
- this.$.storage.setDraftComment(commentLocation, message);
+ this.storage.setDraftComment(commentLocation, message);
}
},
STORAGE_DEBOUNCE_INTERVAL
@@ -945,7 +946,7 @@
return;
}
- const draft = this.$.storage.getDraftComment({
+ const draft = this.storage.getDraftComment({
changeNum,
patchNum: this._getPatchNum(),
path: comment.path,
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.ts
index d6992c8..23dd71a 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_html.ts
@@ -494,5 +494,4 @@
</gr-dialog>
</gr-overlay>
</template>
- <gr-storage id="storage"></gr-storage>
`;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
index ea46ea1..6c925b0 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
@@ -115,7 +115,7 @@
});
test('message is not retrieved from storage when other edits', done => {
- const storageStub = sinon.stub(element.$.storage, 'getDraftComment');
+ const storageStub = sinon.stub(element.storage, 'getDraftComment');
const loadSpy = sinon.spy(element, '_loadLocalDraft');
element.changeNum = 1;
@@ -135,7 +135,7 @@
});
test('message is retrieved from storage when no other edits', done => {
- const storageStub = sinon.stub(element.$.storage, 'getDraftComment');
+ const storageStub = sinon.stub(element.storage, 'getDraftComment');
const loadSpy = sinon.spy(element, '_loadLocalDraft');
element.changeNum = 1;
@@ -458,10 +458,8 @@
},
}));
stubRestApi('removeChangeReviewer').returns(Promise.resolve({ok: true}));
- stub('gr-storage', {
- getDraftComment() { return null; },
- });
element = draftFixture.instantiate();
+ sinon.stub(element.storage, 'getDraftComment').returns(null);
element.changeNum = 42;
element.patchNum = 1;
element.editing = false;
@@ -727,7 +725,7 @@
assert.isTrue(element.editing);
element._messageText = 'hello world';
- const eraseMessageDraftSpy = sinon.spy(element.$.storage,
+ const eraseMessageDraftSpy = sinon.spy(element.storage,
'eraseDraftComment');
const mockEvent = {preventDefault: sinon.stub()};
element._handleSave(mockEvent);
@@ -1026,8 +1024,8 @@
test('cancelling an unsaved draft discards, persists in storage', () => {
const discardSpy = sinon.spy(element, '_fireDiscard');
- const storeStub = sinon.stub(element.$.storage, 'setDraftComment');
- const eraseStub = sinon.stub(element.$.storage, 'eraseDraftComment');
+ const storeStub = sinon.stub(element.storage, 'setDraftComment');
+ const eraseStub = sinon.stub(element.storage, 'eraseDraftComment');
element._messageText = 'test text';
flush();
element.flushDebouncer('store');
@@ -1042,7 +1040,7 @@
test('cancelling edit on a saved draft does not store', () => {
element.comment.id = 'foo';
const discardSpy = sinon.spy(element, '_fireDiscard');
- const storeStub = sinon.stub(element.$.storage, 'setDraftComment');
+ const storeStub = sinon.stub(element.storage, 'setDraftComment');
element._messageText = 'test text';
flush();
element.flushDebouncer('store');
@@ -1240,15 +1238,12 @@
});
test('show tip when no cached record', done => {
- // fake stub for storage
- const respectfulGetStub = sinon.stub();
- const respectfulSetStub = sinon.stub();
- stub('gr-storage', {
- getRespectfulTipVisibility() { return respectfulGetStub(); },
- setRespectfulTipVisibility() { return respectfulSetStub(); },
- });
- respectfulGetStub.returns(null);
element = draftFixture.instantiate();
+ const respectfulGetStub =
+ sinon.stub(element.storage, 'getRespectfulTipVisibility');
+ const respectfulSetStub =
+ sinon.stub(element.storage, 'setRespectfulTipVisibility');
+ respectfulGetStub.returns(null);
// fake random
element.getRandomNum = () => 0;
element.comment = {__editing: true, __draft: true};
@@ -1263,15 +1258,12 @@
});
test('add 14-day delays once dismissed', done => {
- // fake stub for storage
- const respectfulGetStub = sinon.stub();
- const respectfulSetStub = sinon.stub();
- stub('gr-storage', {
- getRespectfulTipVisibility() { return respectfulGetStub(); },
- setRespectfulTipVisibility(days) { return respectfulSetStub(days); },
- });
- respectfulGetStub.returns(null);
element = draftFixture.instantiate();
+ const respectfulGetStub =
+ sinon.stub(element.storage, 'getRespectfulTipVisibility');
+ const respectfulSetStub =
+ sinon.stub(element.storage, 'setRespectfulTipVisibility');
+ respectfulGetStub.returns(null);
// fake random
element.getRandomNum = () => 0;
element.comment = {__editing: true, __draft: true};
@@ -1292,15 +1284,12 @@
});
test('do not show tip when fall out of probability', done => {
- // fake stub for storage
- const respectfulGetStub = sinon.stub();
- const respectfulSetStub = sinon.stub();
- stub('gr-storage', {
- getRespectfulTipVisibility() { return respectfulGetStub(); },
- setRespectfulTipVisibility() { return respectfulSetStub(); },
- });
- respectfulGetStub.returns(null);
element = draftFixture.instantiate();
+ const respectfulGetStub =
+ sinon.stub(element.storage, 'getRespectfulTipVisibility');
+ const respectfulSetStub =
+ sinon.stub(element.storage, 'setRespectfulTipVisibility');
+ respectfulGetStub.returns(null);
// fake random
element.getRandomNum = () => 3;
element.comment = {__editing: true, __draft: true};
@@ -1315,15 +1304,12 @@
});
test('show tip when editing changed to true', done => {
- // fake stub for storage
- const respectfulGetStub = sinon.stub();
- const respectfulSetStub = sinon.stub();
- stub('gr-storage', {
- getRespectfulTipVisibility() { return respectfulGetStub(); },
- setRespectfulTipVisibility() { return respectfulSetStub(); },
- });
- respectfulGetStub.returns(null);
element = draftFixture.instantiate();
+ const respectfulGetStub =
+ sinon.stub(element.storage, 'getRespectfulTipVisibility');
+ const respectfulSetStub =
+ sinon.stub(element.storage, 'setRespectfulTipVisibility');
+ respectfulGetStub.returns(null);
// fake random
element.getRandomNum = () => 0;
element.comment = {__editing: false};
@@ -1347,15 +1333,12 @@
});
test('no tip when cached record', done => {
- // fake stub for storage
- const respectfulGetStub = sinon.stub();
- const respectfulSetStub = sinon.stub();
- stub('gr-storage', {
- getRespectfulTipVisibility() { return respectfulGetStub(); },
- setRespectfulTipVisibility() { return respectfulSetStub(); },
- });
- respectfulGetStub.returns({});
element = draftFixture.instantiate();
+ const respectfulGetStub =
+ sinon.stub(element.storage, 'getRespectfulTipVisibility');
+ const respectfulSetStub =
+ sinon.stub(element.storage, 'setRespectfulTipVisibility');
+ respectfulGetStub.returns({});
// fake random
element.getRandomNum = () => 0;
element.comment = {__editing: true, __draft: true};
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
index 10e8916..2537c1a 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
@@ -35,12 +35,6 @@
}
}
-export interface GrEditableContent {
- $: {
- storage: GrStorage;
- };
-}
-
@customElement('gr-editable-content')
export class GrEditableContent extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
@@ -92,6 +86,8 @@
@property({type: String, observer: '_newContentChanged'})
_newContent?: string;
+ private readonly storage = new GrStorage();
+
_contentChanged() {
/* A changed content means that either a different change has been loaded
* or new content was saved. Either way, let's reset the component.
@@ -112,14 +108,14 @@
'store',
() => {
if (newContent.length) {
- this.$.storage.setEditableContentItem(storageKey, newContent);
+ this.storage.setEditableContentItem(storageKey, newContent);
} else {
// This does not really happen, because we don't clear newContent
// after saving (see below). So this only occurs when the user clears
- // all the content in the editable textarea. But <gr-storage> cleans
+ // all the content in the editable textarea. But GrStorage cleans
// up itself after one day, so we are not so concerned about leaving
// some garbage behind.
- this.$.storage.eraseEditableContentItem(storageKey);
+ this.storage.eraseEditableContentItem(storageKey);
}
},
STORAGE_DEBOUNCE_INTERVAL_MS
@@ -145,7 +141,7 @@
let content;
if (this.storageKey) {
- const storedContent = this.$.storage.getEditableContentItem(
+ const storedContent = this.storage.getEditableContentItem(
this.storageKey
);
if (storedContent?.message) {
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
index 85fbba6..fa18761 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
@@ -71,5 +71,4 @@
>
</div>
</div>
- <gr-storage id="storage"></gr-storage>
`;
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
index 129fda8..a0481ae 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
@@ -99,7 +99,7 @@
});
test('editing toggled to true, has stored data', () => {
- sinon.stub(element.$.storage, 'getEditableContentItem')
+ sinon.stub(element.storage, 'getEditableContentItem')
.returns({message: 'stored content'});
element.editing = true;
@@ -109,7 +109,7 @@
});
test('editing toggled to true, has no stored data', () => {
- sinon.stub(element.$.storage, 'getEditableContentItem')
+ sinon.stub(element.storage, 'getEditableContentItem')
.returns({});
element.editing = true;
@@ -119,9 +119,9 @@
test('edits are cached', () => {
const storeStub =
- sinon.stub(element.$.storage, 'setEditableContentItem');
+ sinon.stub(element.storage, 'setEditableContentItem');
const eraseStub =
- sinon.stub(element.$.storage, 'eraseEditableContentItem');
+ sinon.stub(element.storage, 'eraseEditableContentItem');
element.editing = true;
element._newContent = 'new content';
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts
index 1369a17..a86d8f2 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts
@@ -14,10 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {customElement, property} from '@polymer/decorators';
import {CommentRange, PatchSetNum} from '../../../types/common';
export interface StorageLocation {
@@ -43,28 +39,12 @@
CLEANUP_PREFIXES_MAX_AGE_MAP.set('draft', DURATION_DAY);
CLEANUP_PREFIXES_MAX_AGE_MAP.set('editablecontent', DURATION_DAY);
-declare global {
- interface HTMLElementTagNameMap {
- 'gr-storage': GrStorage;
- }
-}
+export class GrStorage {
+ private lastCleanup = 0;
-export interface GrStorage {
- $: {};
-}
+ private readonly storage = window.localStorage;
-@customElement('gr-storage')
-export class GrStorage extends GestureEventListeners(
- LegacyElementMixin(PolymerElement)
-) {
- @property({type: Number})
- _lastCleanup = 0;
-
- @property({type: Object})
- _storage = window.localStorage;
-
- @property({type: Boolean})
- _exceededQuota = false;
+ private exceededQuota = false;
getDraftComment(location: StorageLocation): StorageObject | null {
this._cleanupItems();
@@ -78,7 +58,7 @@
eraseDraftComment(location: StorageLocation) {
const key = this._getDraftKey(location);
- this._storage.removeItem(key);
+ this.storage.removeItem(key);
}
getEditableContentItem(key: string): StorageObject | null {
@@ -106,7 +86,7 @@
}
eraseEditableContentItem(key: string) {
- this._storage.removeItem(this._getEditableContentKey(key));
+ this.storage.removeItem(this._getEditableContentKey(key));
}
_getDraftKey(location: StorageLocation): string {
@@ -134,20 +114,20 @@
_cleanupItems() {
// Throttle cleanup to the throttle interval.
if (
- this._lastCleanup &&
- Date.now() - this._lastCleanup < CLEANUP_THROTTLE_INTERVAL
+ this.lastCleanup &&
+ Date.now() - this.lastCleanup < CLEANUP_THROTTLE_INTERVAL
) {
return;
}
- this._lastCleanup = Date.now();
+ this.lastCleanup = Date.now();
- Object.keys(this._storage).forEach(key => {
+ Object.keys(this.storage).forEach(key => {
const entries = CLEANUP_PREFIXES_MAX_AGE_MAP.entries();
for (const [prefix, expiration] of entries) {
if (key.startsWith(prefix)) {
const item = this._getObject(key);
if (!item || Date.now() - item.updated > expiration) {
- this._storage.removeItem(key);
+ this.storage.removeItem(key);
}
}
}
@@ -155,7 +135,7 @@
}
_getObject(key: string): StorageObject | null {
- const serial = this._storage.getItem(key);
+ const serial = this.storage.getItem(key);
if (!serial) {
return null;
}
@@ -163,16 +143,16 @@
}
_setObject(key: string, obj: StorageObject) {
- if (this._exceededQuota) {
+ if (this.exceededQuota) {
return;
}
try {
- this._storage.setItem(key, JSON.stringify(obj));
+ this.storage.setItem(key, JSON.stringify(obj));
} catch (exc) {
// Catch for QuotaExceededError and disable writes on local storage the
// first time that it occurs.
if (exc.code === 22) {
- this._exceededQuota = true;
+ this.exceededQuota = true;
console.warn('Local storage quota exceeded: disabling');
return;
} else {
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
index 99f953f..64d3750 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
@@ -16,12 +16,10 @@
*/
import '../../../test/common-test-setup-karma.js';
-import './gr-storage.js';
-
-const basicFixture = fixtureFromElement('gr-storage');
+import {GrStorage} from './gr-storage.js';
suite('gr-storage tests', () => {
- let element;
+ let grStorage;
function mockStorage(opt_quotaExceeded) {
return {
@@ -36,9 +34,8 @@
}
setup(() => {
- element = basicFixture.instantiate();
-
- element._storage = mockStorage();
+ grStorage = new GrStorage();
+ grStorage.storage = mockStorage();
});
test('storing, retrieving and erasing drafts', () => {
@@ -54,23 +51,23 @@
};
// The key is in the expected format.
- const key = element._getDraftKey(location);
+ const key = grStorage._getDraftKey(location);
assert.equal(key, ['draft', changeNum, patchNum, path, line].join(':'));
// There should be no draft initially.
- const draft = element.getDraftComment(location);
+ const draft = grStorage.getDraftComment(location);
assert.isNotOk(draft);
// Setting the draft stores it under the expected key.
- element.setDraftComment(location, 'my comment');
- assert.isOk(element._storage.getItem(key));
- assert.equal(JSON.parse(element._storage.getItem(key)).message,
+ grStorage.setDraftComment(location, 'my comment');
+ assert.isOk(grStorage.storage.getItem(key));
+ assert.equal(JSON.parse(grStorage.storage.getItem(key)).message,
'my comment');
- assert.isOk(JSON.parse(element._storage.getItem(key)).updated);
+ assert.isOk(JSON.parse(grStorage.storage.getItem(key)).updated);
// Erasing the draft removes the key.
- element.eraseDraftComment(location);
- assert.isNotOk(element._storage.getItem(key));
+ grStorage.eraseDraftComment(location);
+ assert.isNotOk(grStorage.storage.getItem(key));
});
test('automatically removes old drafts', () => {
@@ -85,25 +82,25 @@
line,
};
- const key = element._getDraftKey(location);
+ const key = grStorage._getDraftKey(location);
// Make sure that the call to cleanup doesn't get throttled.
- element._lastCleanup = 0;
+ grStorage.lastCleanup = 0;
- const cleanupSpy = sinon.spy(element, '_cleanupItems');
+ const cleanupSpy = sinon.spy(grStorage, '_cleanupItems');
// Create a message with a timestamp that is a second behind the max age.
- element._storage.setItem(key, JSON.stringify({
+ grStorage.storage.setItem(key, JSON.stringify({
message: 'old message',
updated: Date.now() - 24 * 60 * 60 * 1000 - 1000,
}));
// Getting the draft should cause it to be removed.
- const draft = element.getDraftComment(location);
+ const draft = grStorage.getDraftComment(location);
assert.isTrue(cleanupSpy.called);
assert.isNotOk(draft);
- assert.isNotOk(element._storage.getItem(key));
+ assert.isNotOk(grStorage.storage.getItem(key));
});
test('_getDraftKey', () => {
@@ -118,7 +115,7 @@
line,
};
let expectedResult = 'draft:1234:5:my_source_file.js:123';
- assert.equal(element._getDraftKey(location), expectedResult);
+ assert.equal(grStorage._getDraftKey(location), expectedResult);
location.range = {
start_character: 1,
start_line: 1,
@@ -126,12 +123,12 @@
end_line: 2,
};
expectedResult = 'draft:1234:5:my_source_file.js:123:1-1-1-2';
- assert.equal(element._getDraftKey(location), expectedResult);
+ assert.equal(grStorage._getDraftKey(location), expectedResult);
});
test('exceeded quota disables storage', () => {
- element._storage = mockStorage(true);
- assert.isFalse(element._exceededQuota);
+ grStorage.storage = mockStorage(true);
+ assert.isFalse(grStorage.exceededQuota);
const changeNum = 1234;
const patchNum = 5;
@@ -143,37 +140,37 @@
path,
line,
};
- const key = element._getDraftKey(location);
- element.setDraftComment(location, 'my comment');
- assert.isTrue(element._exceededQuota);
- assert.isNotOk(element._storage.getItem(key));
+ const key = grStorage._getDraftKey(location);
+ grStorage.setDraftComment(location, 'my comment');
+ assert.isTrue(grStorage.exceededQuota);
+ assert.isNotOk(grStorage.storage.getItem(key));
});
test('editable content items', () => {
- const cleanupStub = sinon.stub(element, '_cleanupItems');
+ const cleanupStub = sinon.stub(grStorage, '_cleanupItems');
const key = 'testKey';
- const computedKey = element._getEditableContentKey(key);
+ const computedKey = grStorage._getEditableContentKey(key);
// Key correctly computed.
assert.equal(computedKey, 'editablecontent:testKey');
- element.setEditableContentItem(key, 'my content');
+ grStorage.setEditableContentItem(key, 'my content');
// Setting the draft stores it under the expected key.
- let item = element._storage.getItem(computedKey);
+ let item = grStorage.storage.getItem(computedKey);
assert.isOk(item);
assert.equal(JSON.parse(item).message, 'my content');
assert.isOk(JSON.parse(item).updated);
// getEditableContentItem performs as expected.
- item = element.getEditableContentItem(key);
+ item = grStorage.getEditableContentItem(key);
assert.isOk(item);
assert.equal(item.message, 'my content');
assert.isOk(item.updated);
assert.isTrue(cleanupStub.called);
// eraseEditableContentItem performs as expected.
- element.eraseEditableContentItem(key);
- assert.isNotOk(element._storage.getItem(computedKey));
+ grStorage.eraseEditableContentItem(key);
+ assert.isNotOk(grStorage.storage.getItem(computedKey));
});
});