Commit 8c833c3c authored by dpapad's avatar dpapad Committed by Commit Bot

Bookmarks WebUI: Use ES6 class syntax where possible.

Also fix newly found JS Compiler errors (apparently ES6 classes trigger
stricter checks, which is good).

Bug: None
Change-Id: I22460e5e7c2fc6449317c31642ba1f69fe12eccc
Reviewed-on: https://chromium-review.googlesource.com/c/1279412
Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarcalamity <calamity@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599753}
parent 4726a173
......@@ -7,22 +7,21 @@ cr.define('bookmarks', function() {
* Manages focus restoration for modal dialogs. After the final dialog in a
* stack is closed, restores focus to the element which was focused when the
* first dialog was opened.
* @constructor
*/
function DialogFocusManager() {
/** @private {HTMLElement} */
this.previousFocusElement_ = null;
class DialogFocusManager {
constructor() {
/** @private {HTMLElement} */
this.previousFocusElement_ = null;
/** @private {Set<HTMLDialogElement>} */
this.dialogs_ = new Set();
}
/** @private {Set<HTMLDialogElement>} */
this.dialogs_ = new Set();
}
DialogFocusManager.prototype = {
/**
* @param {HTMLDialogElement} dialog
* @param {function()=} showFn
*/
showDialog: function(dialog, showFn) {
showDialog(dialog, showFn) {
if (!showFn) {
showFn = function() {
dialog.showModal();
......@@ -42,46 +41,46 @@ cr.define('bookmarks', function() {
}
showFn();
},
}
/**
* @return {boolean} True if the document currently has an open dialog.
*/
hasOpenDialog: function() {
hasOpenDialog() {
return this.dialogs_.size > 0;
},
}
/**
* Clears the stored focus element, so that focus does not restore when all
* dialogs are closed.
*/
clearFocus: function() {
clearFocus() {
this.previousFocusElement_ = null;
},
}
/** @private */
updatePreviousFocus_: function() {
updatePreviousFocus_() {
this.previousFocusElement_ = this.getFocusedElement_();
},
}
/**
* @return {HTMLElement}
* @private
*/
getFocusedElement_: function() {
getFocusedElement_() {
let focus = document.activeElement;
while (focus.root && focus.root.activeElement)
focus = focus.root.activeElement;
return focus;
},
}
/**
* @param {HTMLDialogElement} dialog
* @return {function(Event)}
* @private
*/
getCloseListener_: function(dialog) {
getCloseListener_(dialog) {
const closeListener = (e) => {
// If the dialog is open, then it got reshown immediately and we
// shouldn't clear it until it is closed again.
......@@ -97,8 +96,8 @@ cr.define('bookmarks', function() {
};
return closeListener;
},
};
}
}
cr.addSingletonGetter(DialogFocusManager);
......
......@@ -9,25 +9,24 @@
*/
cr.define('bookmarks', function() {
/** @constructor */
function Store() {
/** @type {!BookmarksPageState} */
this.data_ = bookmarks.util.createEmptyState();
/** @type {boolean} */
this.initialized_ = false;
/** @type {!Array<DeferredAction>} */
this.queuedActions_ = [];
/** @type {!Array<!StoreObserver>} */
this.observers_ = [];
/** @private {boolean} */
this.batchMode_ = false;
}
class Store {
constructor() {
/** @type {!BookmarksPageState} */
this.data_ = bookmarks.util.createEmptyState();
/** @type {boolean} */
this.initialized_ = false;
/** @type {!Array<DeferredAction>} */
this.queuedActions_ = [];
/** @type {!Array<!StoreObserver>} */
this.observers_ = [];
/** @private {boolean} */
this.batchMode_ = false;
}
Store.prototype = {
/**
* @param {!BookmarksPageState} initialState
*/
init: function(initialState) {
init(initialState) {
this.data_ = initialState;
this.queuedActions_.forEach((action) => {
......@@ -36,28 +35,28 @@ cr.define('bookmarks', function() {
this.initialized_ = true;
this.notifyObservers_(this.data_);
},
}
/** @type {!BookmarksPageState} */
/** @return {!BookmarksPageState} */
get data() {
return this.data_;
},
}
/** @return {boolean} */
isInitialized: function() {
isInitialized() {
return this.initialized_;
},
}
/** @param {!StoreObserver} observer */
addObserver: function(observer) {
addObserver(observer) {
this.observers_.push(observer);
},
}
/** @param {!StoreObserver} observer */
removeObserver: function(observer) {
removeObserver(observer) {
const index = this.observers_.indexOf(observer);
this.observers_.splice(index, 1);
},
}
/**
* Begin a batch update to store data, which will disable updates to the
......@@ -65,18 +64,18 @@ cr.define('bookmarks', function() {
* operation is likely to cause many sequential model updates (eg, deleting
* 100 bookmarks).
*/
beginBatchUpdate: function() {
beginBatchUpdate() {
this.batchMode_ = true;
},
}
/**
* End a batch update to the store data, notifying the UI of any changes
* which occurred while batch mode was enabled.
*/
endBatchUpdate: function() {
endBatchUpdate() {
this.batchMode_ = false;
this.notifyObservers_(this.data);
},
}
/**
* Handles a 'deferred' action, which can asynchronously dispatch actions
......@@ -86,14 +85,14 @@ cr.define('bookmarks', function() {
* directly to the Store.
* @param {DeferredAction} action
*/
dispatchAsync: function(action) {
dispatchAsync(action) {
if (!this.initialized_) {
this.queuedActions_.push(action);
return;
}
this.dispatchInternal_(action);
},
}
/**
* Transition to a new UI state based on the supplied |action|, and notify
......@@ -101,24 +100,24 @@ cr.define('bookmarks', function() {
* action will be queued and performed upon initialization.
* @param {?Action} action
*/
dispatch: function(action) {
dispatch(action) {
this.dispatchAsync(function(dispatch) {
dispatch(action);
});
},
}
/**
* @param {DeferredAction} action
*/
dispatchInternal_: function(action) {
dispatchInternal_(action) {
action(this.reduce_.bind(this));
},
}
/**
* @param {?Action} action
* @private
*/
reduce_: function(action) {
reduce_(action) {
if (!action)
return;
......@@ -127,18 +126,18 @@ cr.define('bookmarks', function() {
// resolved.
if (this.isInitialized() && !this.batchMode_)
this.notifyObservers_(this.data_);
},
}
/**
* @param {!BookmarksPageState} state
* @private
*/
notifyObservers_: function(state) {
notifyObservers_(state) {
this.observers_.forEach(function(o) {
o.onStateChanged(state);
});
},
};
}
}
cr.addSingletonGetter(Store);
......
......@@ -4,50 +4,48 @@
suiteSetup(function() {
cr.define('bookmarks', function() {
const TestStore = function(data) {
bookmarks.Store.call(this);
this.data_ = Object.assign(bookmarks.util.createEmptyState(), data);
this.initialized_ = true;
class TestStore extends bookmarks.Store {
constructor(data) {
super();
this.data_ = Object.assign(bookmarks.util.createEmptyState(), data);
this.initialized_ = true;
this.lastAction_ = null;
/** @type {?PromiseResolver} */
this.initPromise_ = null;
this.enableReducers_ = false;
/** @type {!Map<string, !PromiseResolver>} */
this.resolverMap_ = new Map();
};
TestStore.prototype = {
__proto__: bookmarks.Store.prototype,
this.lastAction_ = null;
/** @type {?PromiseResolver} */
this.initPromise_ = null;
this.enableReducers_ = false;
/** @type {!Map<string, !PromiseResolver>} */
this.resolverMap_ = new Map();
}
/** @override */
init: function(state) {
init(state) {
if (this.initPromise_) {
bookmarks.Store.prototype.init.call(this, state);
this.initPromise_.resolve();
}
},
}
get lastAction() {
return this.lastAction_;
},
}
resetLastAction() {
this.lastAction_ = null;
},
}
get data() {
return this.data_;
},
}
set data(newData) {
this.data_ = newData;
},
}
/** Replace the global store instance with this TestStore. */
replaceSingleton: function() {
replaceSingleton() {
bookmarks.Store.instance_ = this;
},
}
/**
* Enable or disable calling bookmarks.reduceAction for each action.
......@@ -57,18 +55,18 @@ suiteSetup(function() {
* (suitable for integration tests).
* @param {boolean} enabled
*/
setReducersEnabled: function(enabled) {
setReducersEnabled(enabled) {
this.enableReducers_ = enabled;
},
}
/** @override */
reduce_: function(action) {
reduce_(action) {
this.lastAction_ = action;
if (this.enableReducers_)
bookmarks.Store.prototype.reduce_.call(this, action);
if (this.resolverMap_.has(action.name))
this.resolverMap_.get(action.name).resolve(action);
},
}
/**
* Notifies UI elements that the store data has changed. When reducers are
......@@ -76,28 +74,28 @@ suiteSetup(function() {
* UI elements update correctly (eg, tests must replace the whole list
* when changing a single element).
*/
notifyObservers: function() {
notifyObservers() {
this.notifyObservers_(this.data);
},
}
/**
* Call in order to accept data from an init call to the TestStore once.
* @return {Promise} Promise which resolves when the store is initialized.
*/
acceptInitOnce: function() {
acceptInitOnce() {
this.initPromise_ = new PromiseResolver();
this.initialized_ = false;
return this.initPromise_.promise;
},
}
/**
* Track actions called |name|, allowing that type of action to be waited
* for with `waitForAction`.
* @param {string} name
*/
expectAction: function(name) {
expectAction(name) {
this.resolverMap_.set(name, new PromiseResolver());
},
}
/**
* Returns a Promise that will resolve when an action called |name| is
......@@ -106,7 +104,7 @@ suiteSetup(function() {
* @param {string} name
* @return {!Promise<!Action>}
*/
waitForAction: function(name) {
waitForAction(name) {
assertTrue(
this.resolverMap_.has(name),
'Must call expectAction before each call to waitForAction');
......@@ -114,8 +112,8 @@ suiteSetup(function() {
this.resolverMap_.delete(name);
return action;
});
},
};
}
}
return {
TestStore: TestStore,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment