front-end-documentation.md 5.6 KB

Table of Contents

  1. Top level window
  2. 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.

<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:

<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

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.

<div class="stag-popup stag-popup-md" stag-popup-key="my-popup">
   popup content
</div>
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:

closeStagPopup()

Defined in stag-popup.js

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