All of this would greatly benefit from this being more structured, because state management for this looks like it will be painful. To provide the additional structure, without reinventing the wheel, the Contextual Links JS, Quick Edit JS, CKEditor toolbar configuration UI JS and Toolbar JS have all been written using Backbone models & views.

If this module has no secrets plan to expand its features;
If you don't use Backbone.Router;
If you don't use Backbone.Model in Backbone way;
If you don't use Backbone.View to do critical frontend rendering;
If you don't use Backbone.Sync to handle data exchange;

All remaining is a plain object + bundle of custom event listeners; (Or a middleware function to handle & dispatch the actions). This is how Backbone works also, doesn't it? Backbone has no reactive & 2-way data binding.

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

I started to make a new model and view but then realized that we don't need our own module because if we just want track the "Edit mode" state there is already a model that is doing that, Drupal.contextualToolbar.model.

So created a view Drupal.settings_tray.EditModeView that is connected this model. This allows moving a bunch of stuff:

const editMode = localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false';. We don't have to look at local storage at all.

Remove the functions setEditModeState(), toggleEditMode(), isInEditMode(), because can just set or check the state of the model.

$(toggleEditSelector).once('settingstray').on('click.settingstray', toggleEditMode); We were listening for this event on Contextual's toolbar item. Now our view can just this.listenTo(this.model, 'change:isViewing', this.render);

$(toggleEditSelector).trigger('click').trigger('click.settings_tray');. We were triggering clicking the toolbar "Edit" button when the "Quick Edit" contextual links were clicked. Instead now we can just this.model.set('isViewing', false);

1. fixed
2. Not sure where this is. I remove extra lines at the top
3. fixed
4.fixed, also change this function to setContextualLinksHandler
5. fixed
6. fixed.
7. This just moved code but fixed, this actually be put on 1 line with line length of 100.
8. This just moved code but fixed
9. fixed.

To adding Backbone, it needs not move everything into Backbone namespacing. Just make a function call in the right place. Especially now Drupal has a pretty clear vision to move to another framework..

And if our vision really trying to help all frameworks instead one. Soon later, we could split the separated layers into dedicated files, and another non-CORE framework able to reuse the functions without the overhead.

Basically to determine whether the user is in "Edit" mode we need to keep a boolean state. We are currently doing this in the module by listing for the Contextual modules edit button to be clicked. then we are also programmaticly click the button to invoke our state.

The thing is the new state we are tracking is actually the same exact state that the Contextual module is already tracking. We don't need our own state.

So we can totally remove the need for Settings Tray to keep track of the state at all and just react to state changes from the contextual model. It already is taking on the complexity of keeping track of the state.

The fact Contextual module and Settings Tray model are keeping track of the same state in 2 different ways means there is always the potential for something to go wrong and for the 2 states to go out of sync which should never happen. If only Contextual was keeping track of the "Edit" mode state then this would not be a potential problem.