Skip to content

Comments

Implement an opt-in improved JS framework (Snowboard)#354

Closed
bennothommo wants to merge 114 commits intowip/1.2from
wip/framework-rewrite
Closed

Implement an opt-in improved JS framework (Snowboard)#354
bennothommo wants to merge 114 commits intowip/1.2from
wip/framework-rewrite

Conversation

@bennothommo
Copy link
Member

@bennothommo bennothommo commented Nov 25, 2021

REPLACED BY #401

Documentation: wintercms/docs#45

This PR moves towards introducing a new JavaScript framework for Winter, that uses modern JavaScript and removes the hard-dependency to jQuery that has traditionally been the case with Winter and October before it.

If accepted, we intend to make this opt-in, and still provide the option of using the original framework for legacy apps and older browser support.

Goals

  • Rewrite the framework to be modular and give the user full control of what features are to be enabled in the framework, and not impose technical opinions on the developer.
  • Use a vanilla JavaScript approach to remove the need for jQuery and decrease the asset bandwidth considerably.
  • Leverage the power of ES6 classes to allow for inherited code, extensions and bring the code style more in-line with our PHP code.
  • Take advantage of the Node.js ecosystem to provide minification and compatibility with a wide variety of browsers using Babel.
  • Still provide exactly (or as close to as possible) the same functionality that the original framework provides, with a minimum need for rewriting established projects.

Concepts

The four cornerstones of this framework are as follows:

The Snowboard class

Represents the global container for the application. This stores all activated plugins and provides instances of these modules as required. It is synonymous with the Application class of Laravel, or a Vue instance.

The PluginLoader class

The main conduit between a plugin and the Snowboard app. This provides the mechanism for delivering instances of each module (or a single instance of Singleton plugin) and resolves dependencies.

The PluginBase class

A plugin is a specific extension to the Snowboard application. It can contain code that provides new functionality or augments other functionality already registered in the application. A plugin can be reused - in essence, each call to the plugin will create a new instance and will be independent from other instances. This would be used for scenarios such as Flash messages, AJAX requests and the like.

The Singleton class

An extension of the PluginBase class. It signifies to the application that this plugin should exist once, and all uses of this plugin should use the same instance. This would be useful for things like event handlers, extending functionality of another plugin or global functionality.

A singleton is initialized automatically when the DOM is ready, if it is called directly or if it listens to an event that is fired. The singleton instance is then used no matter how many times it is called from the Snowboard class.

What's included

By default, this framework only includes the framework architecture and a couple of utilities. This is an intentional choice to allow the greatest flexibility in how the framework is used. The utilities include:

  • A JSON parser that is customized to handle the established data structure of Winter (and October before it).
  • An HTML sanitizer that provides sanitization for HTML code.
  • A debouncer, that acts similar to the Vue.newTick function in allowing code to run after the previous frame is rendered - useful for ensuring DOM changes are made and events are correctly fired.

In addition, some opt-in features include a rewritten Request class that represents a fresh take on the JavaScript AJAX framework available in Winter. This new Request class leverages the fetch method in all modern browsers to conduct AJAX calls. It supports all options and configuration that were previously available in the original framework.

A second extension - AttributeRequest - provides an augmentation to this functionality and allow the AJAX framework to also handle AJAX calls that use the data- attributes. By separating these features, the developer has the ability to turn off support for the data- attribute AJAX framework should they not need it.

What's not included

  • The HTML data attribute framework allowed for arbitrary JavaScript to be called from within data- attribute callbacks (eg. data-request-success, data-request-error etc.). This feature, at a minimum, prevented sites using content security policies because of its use of the eval() method in JavaScript - at worst, it presented a potential vector for naughtiness. We will not be including this in the framework.

Further notes

  • Due to the usage of Promises, ES6 classes and ES6 syntax, this framework does not support any version of Internet Explorer. It however is supported by all browsers available since 2017 (except for, I suppose, Opera Mini or the Samsung Browser).
  • Node.js will only be required for development of the framework. There will be no need for Node.js usage in themes, plugins, components, etc. (of course, you'll be free to use it in your own development pipeline if you want).
  • More details will be forthcoming as the framework solidifies.

To-do

This reverts commit e9d928a.
This reverts commit 0affd78.
- Sets up architecture of new framework
- Provides some global utilities - JSON Parser, HTML sanitizer and debouncer (similar to Vue.nextTick)
- Defines a new JS Request handler using "fetch()" to make AJAX calls
- Defines a new optional "EnableDataRequest" extension to enable AJAX framework through data attributes
@bennothommo bennothommo changed the title Implement an opt-in improved JS framework Implement an opt-in improved JS framework (Snowboard) Jan 10, 2022
@bennothommo
Copy link
Member Author

bennothommo commented Jan 10, 2022

@LukeTowers

Had another think on this, and I think that this should be included by default in the {% snowboard %} tag but allow for {% snowboard no-attr %} to be used to disable it. IMO the out of box experience of the {% snowboard %} tag should match what the out of box experience of the {% framework %} tag is to ensure that the maximum default support for the features is available for the plugin / theme ecosystem. We can still allow for the no- flags to cut out undesired pieces by the theme devs, but then that is an explicit action that accepts responsibility for that theme's ability to support the plugin ecosystem at large out of the box.

I'm of the opposite opinion. I find it instantly more readable for the Snowboard tag to include which features it is using. If I'm looking at a couple of themes, I feel it would be easier to see {% snowboard request data-attr %} or {% snowboard request extras %}, etc. because then I can immediately tell they're using those features. By contrast, {% snowboard no-data-attr %} makes it clear they're not using data attributes, but doesn't say what features they are using.

I don't think it'll be a friction for people to have to explicitly add which features they want to use (or use {% snowboard all %} to use everything). The other benefit is that if we decide to add new features down the line, and add another key to the tag, it becomes opt-in - the theme developers specifically need to add it to the tag if they wish to include the new feature. The other thing is that the original framework made the "extras" opt-in, which I assume we would need to keep in Snowboard too. So we'll end up with {% snowboard no-data-attr extras %} which could be misinterpreted on first pass to say we're not using data attributes or extras.

@bennothommo bennothommo marked this pull request as ready for review January 10, 2022 02:20
@LukeTowers LukeTowers added this to the v1.2.0 milestone Jan 10, 2022
@bennothommo bennothommo changed the base branch from develop to wip/1.2 January 12, 2022 03:41
@bennothommo
Copy link
Member Author

Work continued in #401 to target the 1.1.8 release.

@bennothommo bennothommo removed this from the v1.2.0 milestone Jan 12, 2022
@LukeTowers LukeTowers added this to the v1.1.8 milestone Feb 15, 2022
@LukeTowers LukeTowers deleted the wip/framework-rewrite branch February 15, 2022 16:42
@mjauvin mjauvin removed this from the v1.1.8 milestone Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement PRs that implement a new feature or substantial change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants