## Table of Contents

1. [Top level window](#top-level-window)
2. [The MC engine](#the-mc-engine)


___
## Top level window

When the top level window receives a request, it does the following:

1. Check if URL has /mc/ prefix
2. If no:
    1. Redirect to /mc/{request-path}
3. If yes:
    1. Load (via AJAX) {request-path} into LHS
    2. Load blank video page into RHS (the one that shows MCP queue at the bottom)

The top level window object exposes the following app-specific methods:

1. `openInLHS(_url)`
2. `openInRHS(_url)`
3. `toggleRHS()`
4. `showRHS()`
5. `hideRHS()`

The above are defined in **mc.blade.php** - which is included *only* from the top level window - and *never* from the LHS or RHS child windows.

---
## The MC engine

Responsible for loading, initialization, history state management, fastLoading, reloads, etc. of the LHS

Assuming the URL as **/mc/path/to-page**, a page load in the LHS involves the following:

1. Fetch **/path/to-page** via AJAX GET
2. Fill LHS with the retrieved content (including any scripts that it includes) - **more on this below**
3. Enable *fast loading* for all `<a>` tags with a href that are not `[native]` - **more on this below**
4. Run all registered **mc initializers** - **more on this below**

---
### Fill LHS with the retrieved content & fast loading

After loading /path/to/page via AJAX, mc extracts the html inside the first `.stag-content` it encounters in the content - and replaces the existing `.stag-content` element in the DOM.

The `.stag-content` element is at `resources/views/layouts/template.blade.php` - line 186

mc.blade.php (the blade responsible for rendering the LHS anf RHS frame elements) initially loads the LHS with **/blank** - an empty page that has 1 `.stag-content` element in it to make subsequent loads work correctly.  

The method `fastLoad(_url)` is available to be called from anywhere in code from with the LHS frame. It will load and display _url in LHS. There is also a `fastReload()` (which btw, will not auto-reset the scrollbar to the top).

> **Important:** `fastLoad()` & `fastReload()` **will not disrupt** any calls that maybe taking place in the RHS

> **Note:** The top header nav is outside `.stag-content` and is **not** refreshed during `fastLoad()` & `fastReload()`

---
### Enable fast loading for all `<a>` tags in the content

Once the content is retrieved and inserted into `.stag-content`, we automatically bind fast load events into all `<a>` that are not `[native]` and that have a valid `[href]`

All link clicks (other than those bound to context specific JS events - like Vue code etc.) work via the above loader - fetching and inserting only the content area. 

To prevent any link from being auto-enabled for fast loading, add the **native** attribute to it. 

```html
<a native target="_top" href="/foo/bar">Some Link</a>
```

---
### Run all registered mc initializers

Because page content is loaded via AJAX and inserted into the DOM, we cannot rely on `document.onready` for running init code.

Any page specific code that needs to be run on start up, must go into an **mc initializer*. The mc engine, keeps track of all registered initializers are runs all required initers after each fastLoad (or reload).

Writing start up code for a page. Example:

```html
<div id="my-page">
   Some content
</div>
<script>
   (function () {
      function init() {
         // init code goes here
      }

      // add your initializer to mc stack
      addMCInitializer('my-page', init, '#my-page');
      
   }).call(window);
</script>
```

1. The first arg to `addMCInitializer()` is a name for the initializer (more on why these are named later)
2. Second arg is the function to be called
3. The Third argument is a container element - whose presence in the DOM will be checked before executing the initer. If this element is not present, the initer will be deleted from the list of registered initializers
4. On all pages, page specific JS is **always** wrapped inside a scope-limiting [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)

> **Why named initializers**
>  
> Sometimes, we'll need to selectively run some initializers - for example, if we're loading a note single inside a popup, we'll need to grab just the note page markup (without mc, the layout, etc.) - but will still need to run its initializer after the popup is filled for the functionality inside to work. In such cases, we can call `runMCInitializer('note-single)` for example.

> Special case **window.noMC**
>
> If window.noMC is true, the above flow is overridden, and the page is allowed to load as-is regardless of the presence/absence of /mc/ in the URL.

> Defined in mc-init.js & mc.js

---
## Stag Popups

Medium to big popups (different from moes). Identified via the `[stag-popup-key]` attribute and displayed using the `showStagPopup(_key)` method call.

```html
<div class="stag-popup stag-popup-md" stag-popup-key="my-popup">
   popup content
</div>
```
```javascript
showStagPopup('my-popup')
```

Stag popup maintains an app-level popup stack. You can have a popup over a popup over a popup. Clicking anywhere outside or hitting ESC will close the topmost stag-popup and so on. Stag popups can also have regular moes within their content.

If a stag-popup has the attribute `[close-all-with-self]` - then all stag-popups are closed along with it (regardless of the number of stacked popups currently open)

Stag popups with `.stag-slide` class will slide in from the right (instead of appearing at the center).

To close the topmost stag popup:
```javascript
closeStagPopup()
```

> Defined in stag-popup.js

Yemi mods Shortcuts Stag-popup Note > templates Pro-suggest, Pharmacy suggest Popupmode queryline param
