We've removed the ability to directly reference JS and CSS files
for form fields and other SilverStripe features in favour of a common bundle built by Webpack.
The logical next step is to make the framework module free of frontend dependencies,
which should simplify its operation, and avoid another time intensive "npm install" on a module.
Used in iframe, so can't be rolled into other code.
Moved in admin/ since that's easier for now with Webpack entry points,
and we'll move all JS/CSS into admin/ anyway soon.
There's not a lot of benefit in packaging these separately in terms of initial CMS load size,
so let's simplify the setup. They'll eventually become lazy loaded chunks in a React-based setup
When adding the deps straight into the file (recommended),
the onchange handler in file-upload isn't firing properly when a file is uploaded through
the <input type=file> button - it falls back to default behaviour, which submits the
containing form, failing because the upload is handled by a different URL.
These were originally copied from node_modules via an "npm run thirdparty" task,
in order to have them loadable with oldschool <script> tags.
Since webpack supports CommonJS-style loading, that's no longer required,
we can simply inline those scripts into the bundle.
We need to use imports-loader though, in order to ensure
that "define" is not available in some module scopes,
which triggers AMD behavior that's not compatible with Webpack's loaders.
See http://webpack.github.io/docs/shimming-modules.html
I've had to pin to the exact versions used in the 3.x CMS,
since jquery-upload has introduced an AMD wrapper sometime
between 6.0 and 6.9 (the latest version NPM automatically pulls in).
This AMD wrapper confuses Webpack, since it's trying to resolve the
dependencies contained in it. We could create shims for those instead,
but the easiest way was to simply revert to the versions already used
before the Webpack migration (since the newer versions in node_modules
were never actually copied into thirdparty, they weren't used before).
Many of these are now inline via Webpack's url-loader plugin (https://github.com/webpack/url-loader),
and a tonne were legacy references (e.g. leftovers from ComplexTableField).
Some of these might still be used in other modules like userforms,
but we're removing support for "hotlinking" images in core - they're not an API.
Responsibility for finding and referencing images and fonts is now
given to webpack. All the url references are now relative to the
component scss file, and point to font & images files in src/, rather
than assuming someone else will place them in dist.
This makes the source more modular, and makes it easier to, for
example, inline images are data URIs, or create a new build script that
builds several modules for a project in a single pass.
Workaround for bad font path in bundle.css:
ExtactTextPlugin didn’t work as well with a subfolder reference in the
filename. This is just a short-term fix and could probably be improved
to put bundle.css back in the styles subfolder.
Webpack handles images & fonts:
Responsibility for finding and referencing images and fonts is now
given to webpack. All the url references are now relative to the
component scss file, and point to font & images files in src/, rather
than assuming someone else will place them in dist.
This makes the source more modular, and makes it easier to, for
example, inline images are data URIs, or create a new build script that
builds several modules for a project in a single pass.
Clarify docs on spriting and webfonts:
We've decided to remove sprity since it comes with hundreds of dependencies,
and needs compilation within the "npm install" - dragging out the already overweight
install process, and making the resulting node_modules/ folder less portable between systems.
The bundle is generated by running “webpack” directly - gulp is no
longer needed as an intermediary. The resulting config is a lot shorter,
although more configuration is pushed into lib.js.
Modules are shared between javascript files as global variables.
Although this global state pollution is a bit messy, I don’t think it’s
practically any worse than the previous state, and it highlights the
heavy coupling between the different packages we have in place.
Reducing the width of the coupling between the core javascript and
add-on modules would probably be a better way of dealing with this than
replacing global variables with some other kind of global state.
The web pack execution seems roughly twice as fast - if I clear out my
framework/client/dist/js folder, it takes 13.3s to rebuild. However,
it’s not rebuilding other files inside dist, only the bundle files.
CSS files are now included from javascript and incorporated into
bundle.css by the webpack. Although the style-loader is helpful in some
dev workflows (it allows live reload), it introduces a flash of
unstyled content which makes it inappropriate for production.
Instead ExtractTextPlugin is used to write all the aggregated CSS
into a single bundle.css file. A style-loader-based configuration could
be introduced for dev environments, if we make use of the webpack live
reloader in the future.
Note that the following features have been removed as they don't appear to be
necessary when using Webpack:
- UMD module generation
- thirdparty dist file copying
LeftAndMain.js deps: Without it, ssui.core.js gets loaded too late,
which leads e.g. to buttons being initialised without this added behaviour.
Introducing <Tabs> component based on react-bootstrap
Better support for nested fields in FormBuilder
Tweaks to get FormBuilder working with frameworktest BasicFieldsPage fields
Added exception in FormBuilder when Component is defined but not found
Added check in SingleSelectField for empty value before adding one in
Added temporary workaround for CompositeFields with no name (another story to address the actual problem)
Added asset_preview_height for File image preview, matches the defined CSS max-height
Added documentation to DBFile::PreviewLink() method
* Remove interference of nested for__fieldgroup-item
* Adjust position of dropdown field
* Remove divider lines, adjust position of upload area
Clean up styles a bit too
* Adjust position of image
* Mostly css tidy up, added use of a few variables
* Toggle arrow was showing other icon because of icon height
* All buttons in toolbars remove margin below, adjust button link color
* Reorder sort and filter, add toolbar styles
* Add button styles to toolbar
* Remove some of the linting issues
* Added new panel variables
* Simplify variable
* Replace panel variable, insert media dialog positioning
* Update with new variable name, reduce space below toolbar
* Build
* Uploading file spacing, toolbar styles added
* Visual uploads, error upload fixes, edit details panel spacing
* Add toolbar to upload modal
* build
* Build
* increase width of pagination on gridfield
* Add height to uploading items only
* Build
* Added class back for beat test to pass
This caught us out recently where code did a strict type check for `myVar === undefined`.
The var was defined as `let myVar;`, without a value - so the check returned false (it's `null`).
To avoid this situation, we've decided to enforce declarations with values.
Note that preference should be given to single, immutable assignments via const where possible.
See http://eslint.org/docs/rules/init-declarations
Allows actions to make decisions based on the form payload.
For example, a "delete" button can pass the currently edited record ID to its API endpoint.
Form element styles should be consistent throughout the CMS.
While we still have the ability to create dropdowns (<select>) which aren't based on
Entwine/HTML rather than new components like <SingleSelectField>,
we need to ensure those are rendered the same.
By default, the Entwine-based CMS sections will transform <select>
into a ChosenJS control, but you can still apply .no-chosen.
Hence there's a need for correct height both in React and Entwine sections,
not just in a React component.
Standardise template locations
Move CMSSettingsController class to SiteConfig module
Fix CMSMenu behaviour for namespaced admin sections
Split classes into one per file
Manual fixes and cleanup
Convert form and Textfield styles to use Bootstrap
Split out btn styles a bit more clearly defined (BEM)
Toolbar modifier to improve spacing for smaller screens
Use bootstrap spacer styles .m-t-1 (margin-top-1 x spacer) instead of custom spacer
Added a few typography helpers
Tab styles continued although they are hidden (used on AssetAdmin editor panel)
Required to support new "compressed" form style in admin/assets
which puts form field labels on their own line (and requires the bootstrap layout styling for this)
* Swap out .Actions class for bootstrap .btn-toolbar
* Converted all south toolbars to use new toolbar component styles, content and preview styles for scrollbars adjusted where required
This should be separated out to a common FormField class,
but for now we're only using TextField. Can be solved
properly at the same time as switching form fields to
react-bootstrap.
Required for readonly field value alignment in the "campaigns" edit form.
Better than no feedback at all while campaigns are loading.
Not using spinner.gif because a loading animation is already presented when the section is loaded (via PJAX).
Not translating the "Loading..." text because its temporary.
We're not using it for any other props passed to ReactJS components,
so there's no reason to do it here. Props are immutable by convention.
While it would be nice to enforce this, its too common to pass through
function objects which aren't supported by IE's Object.freeze().
IE isn't following the spec on how to handle Object.freeze(function() {}).
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#Notes
> In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return it.
MS docs on https://msdn.microsoft.com/en-us/subscriptions/downloads/ff806186(v=vs.94).aspx
> If the object argument is not an object, a TypeError exception is thrown.