Autoloading improved, utilities now global (#225)

* Autoloading improved, utilities now global

# Autoloading

Webpack специально не дает использовать переменные в реквайрах типа:

let moduleName = 'toolbar.js';
let module = require(moduleName);

У нас в автолоадинге было так:

let modules = editorModules.map( module =>
require('./components/modules/' + module ));

и это работало, но не так как нужно. Он подключал не только нужные
модули из массива editorModules, а вообще все модули из папки
components/modules. Я заметил, что они попадают в сборку, хоть и не
указаны в реквайрах. Оказывается это так и задумано: Webpack на этапе
компиляции не знает что будет в переменной, то есть какой там будет
модуль. А ему нужно высчитать время компиляции, поэтому он вкладывет в
сброрку тупо все файлы из этой папки, и для каждого высчитывает время.
Так что по сути это было то же самое что просто написать
require('./components/modules/') и подключить все файлы.

Но наш автолоадер должен был подключать только указанные файлы, не
заходить в подпапки и не включать файлы, начинающиеся с подчеркивания.

Теперь автолоадинг работает так, как и задумывалось.

# Global visible modules

Теперь не нужно в каждом файле писать

import $ from '../dom';

и тд. Они автоматически будут доступны внутри модулей

* Update util.Dom

* Remove duplicated Babel helpers. Now it will be defined at once
This commit is contained in:
Peter Savchenko 2017-12-02 15:35:55 +03:00 committed by GitHub
parent 56e1641339
commit 5f670c3985
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 890 additions and 6045 deletions

View file

@ -72,7 +72,9 @@
"FormData": true,
"XMLHttpRequest": true,
"ActiveXObject": true,
"RegExp": true
"RegExp": true,
"$": true,
"_": true
}
}

4
.gitignore vendored
View file

@ -10,3 +10,7 @@ node_modules/*
/uploads/
plugins/personality/
npm-debug.log
build/__tmp_babel_helpers.js

View file

@ -12,7 +12,10 @@
// Define globals exposed by CodeX Team
"predef": [
"codex"
"codex",
"_",
"$",
"editorModules"
],
// Allow ES6.

View file

@ -1,636 +0,0 @@
/**
* CodeX Editor stylesheets
* @author CodeX Team https://ifmo.su
*
* https://github.com/codex-team/codex.editor
*/
@import url('icons.css');
/**
* Editor wrapper
*/
.codex-editor{
position: relative;
}
.codex-editor .hide {
display: none;
}
/**
* Working zone - redactor
*/
.ce-redactor{
position: relative;
padding-bottom: 120px;
min-height: 350px;
}
.ce-block__content a {
color: #186baa;
}
/*.ce-redactor * {
box-sizing: border-box;
}*/
/**
* Remove outlines from inputs
*/
.ce-redactor [contenteditable]{
outline: none !important;
}
/**
* Toolbar
*/
.ce-toolbar{
position: absolute;
z-index: 2;
width: 100%;
/* hidden by default */
display: none;
}
.ce-toolbar.opened{
display: block;
}
.ce-toolbar__content {
position: relative;
max-width: 600px;
margin: 0 auto;
}
/**
* Plus button
*/
.ce-toolbar__plus{
position: absolute;
background-image: url('fonts/codex_editor/icon-plus.svg');
background-position: center center;
background-repeat: no-repeat;
text-align: center;
transition: transform 100ms ease;
will-change: transform;
margin-left: -50px;
}
.ce-toolbar__plus.clicked{
transform: rotate(45deg);
}
/**
* Tools list
*/
.ce-toolbar__tools{
position: absolute;
top: 0;
left: 0;
/* hidden by default */
opacity: 0;
visibility: hidden;
transform: translateX(-100px);
transition: all 150ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
}
.ce-toolbar__tools.opened{
opacity: 1;
visibility: visible;
transform: none;
}
.ce-toolbar__plus,
.ce-toolbar__tools li {
display: inline-block;
width: 32px;
height: 32px;
background-color: #eff2f5;
/*box-shadow: 0 0 0 1px #6d748c;*/
margin-right: 17px;
border-radius: 16px;
text-align: center;
vertical-align: top;
cursor: pointer;
font-size: 14px;
will-change: transform, margin-right;
transition: transform 200ms cubic-bezier(0.600, -0.280, 0.735, 0.045), margin 200ms ease-out;
}
.ce-toolbar__tools li i{
line-height: 32px;
}
.ce-toolbar__tools li:hover,
.ce-toolbar__tools .selected{
background: #383b5d;
box-shadow: none;
color: #fff;
}
/* animation for tools opening */
.ce-toolbar__tools li{
transform: rotate(-180deg) scale(.7);
margin-right: -15px;
}
.ce-toolbar__tools.opened li{
transform: none;
margin-right: 17px;
}
/**
* Toolbar right zone with SETTINGS and DELETE
*/
.ce-toolbar__actions{
position: absolute;
right: 15px;
border-radius: 2px;
padding: 6px 5px;
line-height: 1em;
font-size: 14px;
background: #fff;
}
/**
* Settings button
*/
.ce-toolbar__settings-btn{
margin-right: .3em;
cursor: pointer;
}
.ce-toolbar__settings-btn,
.ce-toolbar__remove-btn{
color: #5e6475;
}
.ce-toolbar__settings-btn:hover,
.ce-toolbar__remove-btn:hover{
color: #272b35
}
/**
* Settigns panel
*/
.ce-settings,
.ce-toolbar__remove-confirmation{
position: absolute;
right: 0;
margin-top: 10px;
min-width: 200px;
background: #FFFFFF;
border: 1px solid #e7e9f1;
box-shadow: 0px 2px 5px 0px rgba(16, 23, 49, 0.05);
border-radius: 3px;
white-space: nowrap;
color: #2b2d31;
font-size: 13.4px;
/* hidden by default */
display: none;
}
/**
* Settings and remove-confirmation corner
*/
.ce-settings:before,
.ce-toolbar__remove-confirmation:before,
.ce-settings:after,
.ce-toolbar__remove-confirmation:after{
content: "";
position: absolute;
top: -14px;
right: 10px;
border-style: solid;
}
.ce-settings:before,
.ce-toolbar__remove-confirmation:before {
margin: -2px -1px 0;
border-width: 8px;
border-color: transparent transparent #e7e9f1 transparent;
}
.ce-settings:after,
.ce-toolbar__remove-confirmation:after {
border-width: 7px;
border-color: transparent transparent #fff transparent;
}
.ce-settings:before,
.ce-settings:after{
right: 31px;
}
.ce-toolbar__remove-confirmation:before,
.ce-toolbar__remove-confirmation:after{
right: 10px;
}
.ce-toolbar__remove-confirmation{
right: -3px;
}
/**
* Plugins settings style helper
*/
.cdx-plugin-settings--horisontal {
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.cdx-plugin-settings--horisontal .cdx-plugin-settings__item {
flex: 1 0 auto;
text-align: center;
}
.ce-settings__item,
.ce-toolbar__remove-confirm,
.ce-toolbar__remove-cancel,
.cdx-plugin-settings__item {
padding: 15px;
cursor: pointer;
line-height: 1em;
}
.ce-settings__item:hover,
.ce-toolbar__remove-cancel:hover,
.cdx-plugin-settings__item:hover {
background: #edf0f5;
}
.ce-settings.opened,
.ce-toolbar__remove-confirmation.opened{
display: block;
}
.ce-settings_plugin{
border-bottom: 1px solid #e7e9f1;
}
.ce-settings_plugin:empty{
display: none;
}
.ce-settings__item:not(:last-of-type) {
border-bottom: 1px solid #e7e9f1;
}
.ce-settings__item i,
.cdx-plugin-settings__item i {
min-width: 16px;
margin-right: 1.3em;
}
.ce-settings__item i::before {
min-width: 16px;
margin: 0;
}
/**
* Trash button
*/
.ce-toolbar__remove-btn {
cursor: pointer;
}
.ce-toolbar__remove-confirm{
color: #ea5c5c;
}
.ce-toolbar__remove-confirm:hover{
background: #e23d3d;
color: #fff;
}
/** Anchor input */
.ce-settings__anchor-wrapper:hover {
background: none;
}
.ce-settings__anchor-input {
max-width: 100%;
border: 0;
outline: none;
padding: 14px 0;
margin: -15px 0;
font-size: inherit;
color: #000;
height: 1em;
}
.ce-settings__anchor-input::-webkit-input-placeholder {color: rgba(112, 118, 132, 0.5);}
.ce-settings__anchor-input::-moz-placeholder {color: rgba(112, 118, 132, 0.5);}
.ce-settings__anchor-input:-moz-placeholder {color: rgba(112, 118, 132, 0.5);}
.ce-settings__anchor-input:-ms-input-placeholder {color: rgba(112, 118, 132, 0.5);}
.ce-settings__anchor-hash {
display: inline-block;
background: url('fonts/codex_editor/icon-hash.svg') no-repeat center center;
background-size: contain;
height: 11px;
width: 10px;
vertical-align: middle;
}
/**
* Overlayed inline toolbar
*/
.ce-toolbar-inline{
position: absolute;
left: 0;
top: 0;
z-index: 3;
background: #242533;
border-radius: 3px;
padding: 0 5px;
margin-top: -.5em;
will-change: transform;
transition: transform .2s cubic-bezier(0.600, -0.280, 0.735, 0.045);
color: #fff;
/* hidden by default */
display: none;
}
.ce-toolbar-inline.opened {
display: block;
}
.ce-toolbar-inline__buttons{
}
.ce-toolbar-inline__buttons button{
background: none;
border: 0;
margin: 0 !important;
height: auto !important;
padding: 13px 9px;
line-height: 1em;
color: inherit;
font-size: 12px;
cursor: pointer;
}
.ce-toolbar-inline__buttons button:hover{
background: #171827;
color: #428bff;
}
.ce-toolbar-inline__actions{
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
border-radius: 3px;
background: #242533;
display: none;
}
.ce-toolbar-inline__actions.opened{
display: block;
}
.ce-toolbar-inline__actions input{
background: transparent !important;
border : 0 !important;
box-sizing: border-box !important;
padding: 12px;
font-size: 13px;
width: 100%;
color: #fff;
outline: none;
}
.ce-toolbar-inline__actions input::-moz-placeholder{ color: #afb4c3 !important;}
.ce-toolbar-inline__actions input::-webkit-input-placeholder{ color: #afb4c3 !important;}
/**
* Base blocks
*/
.ce-block {
margin: 0 5px;
border-radius: 3px;
}
.ce-block--focused {
background: #f9f9fb;
}
.ce-block--feed-mode {
position: relative;
}
.ce-block--feed-mode:before {
content: '\e81b';
font-family: "codex_editor";
display: inline-block;
position: absolute;
left: 17px;
top: 13px;
font-size: 16px;
color: #7d6060;
}
.ce-block--anchor {
position: relative;
}
.ce-block--anchor::after {
display: inline-block;
content: "#" attr(data-anchor);
color: #868896;
position: absolute;
left: 17px;
top: 13px;
max-width: 100px;
word-wrap: break-word;
font-size: 12px;
line-height: 1.4em;
}
/**
* Block content holder
*/
.ce-block__content{
max-width: 600px;
margin: 0 auto;
padding: 1px;
}
.ce-block--stretched{
max-width: none;
padding: 0;
}
.cdx-unavailable-block {
display: block;
margin: 10px 0;
padding: 80px;
background-color: #fff7f7;
text-align: center;
border-radius: 3px;
color: #ce5f5f;
}
/**
* Typographycs
*/
.ce-redactor p{
margin: 0;
}
/**
* Loading bar class
*/
.ce-redactor__loader {
background-image: repeating-linear-gradient(-45deg, transparent, transparent 4px, #f5f9ff 4px, #eaedef 8px) !important;
background-size: 56px 56px;
animation: loading-bar 600ms infinite linear;
}
@keyframes loading-bar {
100% { background-position: -56% 0 }
}
/**
* Notifications
*/
.cdx-notifications-block {
position: fixed;
bottom: 0;
left: 0;
padding: 15px;
}
.cdx-notification__notification-appending div {
animation: notification 100ms infinite ease-in;
}
@keyframes notification {
0% { transform: translateY(20px); }
100% { transform: translateY(0px); }
}
.cdx-notification {
width: 250px;
margin-top: 15px;
padding: 15px;
background: #fff;
border: 1px solid #e7e9f1;
box-shadow: 0px 2px 5px 0px rgba(16, 23, 49, 0.05);
border-radius: 3px;
font-size: 14px;
}
.cdx-notification__message {
margin-bottom: 15px;
}
.cdx-notification__ok-btn,
.cdx-notification__cancel-btn {
padding: 4px 7px;
cursor: pointer;
background: #4584d8;
color: #fff;
min-width: 50px;
display: inline-block;
text-align: center;
border-radius: 2px;
}
.cdx-notification__cancel-btn {
margin-left: 10px;
background: #dae0e8;
color: inherit;
}
.cdx-notification__cancel-btn {
background: #cad5e2;
}
.cdx-notification__ok-btn:hover {
background: #3d77c3;
}
.cdx-notification__input {
display: block;
width: 100%;
margin-bottom: 15px;
border: none;
outline: none;
padding: 2px 0;
font-size: inherit;
border-bottom: 2px solid #d1d3da;
}
.cdx-notification-error {
border-left: 4px solid rgb(255, 112, 112);
}
.cdx-notification-warn {
border-left: 4px solid rgb(79, 146, 247);
}
/**
* Mobile viewport styles
* =================================
*/
@media all and (max-width: 1000px){
.ce-block{
margin: 0;
}
.ce-block__content,
.ce-toolbar__content
{
padding: 0 25px;
}
.ce-toolbar {
margin-top: 5px;
}
.ce-toolbar__actions {
right: 0;
top: -10px;
font-size: 14px;
line-height: 18px;
}
.ce-toolbar__settings-btn {
display: block;
margin-bottom: 3px;
}
.ce-toolbar__plus {
margin-left: -25px;
}
.ce-toolbar__plus,
.ce-toolbar__tools li {
width: 22px;
height: 22px;
}
.ce-toolbar__tools li i {
line-height: 22px;
}
.ce-toolbar__tools {
left: 30px;
font-size: 13px;
}
.ce-block--anchor::after {
display: none;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -54,7 +54,6 @@
<!--<link rel="stylesheet" href="plugins/attaches/attaches.css">-->
<script src="../build/codex-editor.js?v=108"></script>
<link rel="stylesheet" href="../build/codex-editor.css?v=11000">
<script>

View file

@ -4,7 +4,7 @@
"description": "Codex Editor. Native JS, based on API and Open Source",
"main": "index.js",
"scripts": {
"build": "webpack --progress --display-error-details --display-entrypoints --display-reasons"
"build": "webpack --progress --display-error-details --display-entrypoints"
},
"author": "Codex Team",
"license": "ISC",
@ -12,6 +12,7 @@
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-class-display-name": "^2.1.0",
"babel-plugin-transform-helper": "0.0.6",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-runtime": "^6.26.0",

View file

@ -55,11 +55,7 @@
* Require Editor modules places in components/modules dir
*/
// eslint-disable-next-line
let modules = editorModules.map( module => {
return require('./components/modules/' + module );
});
let modules = editorModules.map( module => require('./components/modules/' + module ));
/**
* @class

View file

@ -1,7 +1,7 @@
/**
* DOM manupulations helper
*/
export default class Dom {
module.exports = class Dom {
/**
* Helper for making Elements with classname and attributes

View file

@ -1,8 +1,3 @@
/**
* DOM manipulations
*/
import $ from '../dom';
/**
*
* «Toolbar» is the node that moves up/down over current block

View file

@ -32,7 +32,6 @@
* @property {Object} toolsClasses - all classes
* @property {EditorConfig} config - Editor config
*/
let util = require('../util');
class Tools {
@ -102,8 +101,6 @@ class Tools {
*/
prepare() {
let self = this;
if (!this.config.hasOwnProperty('tools')) {
return Promise.reject("Can't start without tools");
@ -133,7 +130,7 @@ class Tools {
/**
* to see how it works {@link Util#sequence}
*/
return util.sequence(sequenceData, (data) => {
return _.sequence(sequenceData, (data) => {
this.success(data);

View file

@ -36,10 +36,6 @@ let CSS = {
editorZone : 'ce-redactor'
};
import $ from '../dom';
/**
* @class
*

View file

@ -20,7 +20,7 @@ module.exports = class Util {
*/
static sequence(chains, success, fallback) {
return new Promise(function (resolve, reject) {
return new Promise(function (resolve) {
/**
* pluck each element from queue
@ -36,7 +36,7 @@ module.exports = class Util {
.then(() => {
// finished
if (iteration == chains.length - 1) {
if (iteration === chains.length - 1) {
resolve();
@ -53,25 +53,25 @@ module.exports = class Util {
*
* @param {ChainData} chainData
*
* @param {Function} success
* @param {Function} fallback
* @param {Function} successCallback
* @param {Function} fallbackCallback
*
* @return {Promise}
*/
function waitNextBlock(chainData, success, fallback) {
function waitNextBlock(chainData, successCallback, fallbackCallback) {
return new Promise(function (resolve, reject) {
return new Promise(function (resolve) {
chainData.function()
.then(() => {
success(chainData.data);
successCallback(chainData.data);
})
.then(resolve)
.catch(function () {
fallback(chainData.data);
fallbackCallback(chainData.data);
// anyway, go ahead even it falls
resolve();

View file

@ -52,7 +52,7 @@ module.exports = {
watch: true,
watchOptions: {
aggregateTimeOut: 50
aggregateTimeout: 50
},
devtool: NODE_ENV == 'development' ? 'source-map' : null,
@ -62,7 +62,11 @@ module.exports = {
*/
resolve : {
// fallback: path.join(__dirname, 'node_modules'),
modules : [ path.join(__dirname, "src"), "node_modules"]
modules : [ path.join(__dirname, "src"), "node_modules"],
alias: {
'utils': path.resolve(__dirname + '/src/components/', './utils'),
'dom': path.resolve(__dirname + '/src/components/', './dom'),
}
},
//
@ -81,6 +85,30 @@ module.exports = {
editorModules: JSON.stringify(editorModules)
}),
/**
* Automatically load global visible modules
* instead of having to import/require them everywhere.
*/
new webpack.ProvidePlugin({
'_': 'utils',
'$': 'dom'
}),
/**
* Setting up a dynamic requires that we use to autoload Editor Modules from 'components/modules' dir
* {@link https://webpack.js.org/plugins/context-replacement-plugin/}
*/
new webpack.ContextReplacementPlugin(
/src\/components\/modules/,
false, // newContentRecursive=false because we dont need to include folders
new RegExp(
'[^_]' + // dont match names started with '_'
`(${editorModules.join('|')})` + // module names pattern: (events.js|ui.js|...)
'$' // at the end of path
)
),
/** Минифицируем CSS и JS */
// new webpack.optimize.UglifyJsPlugin({
/** Disable warning messages. Cant disable uglify for 3rd party libs such as html-janitor */
@ -103,14 +131,25 @@ module.exports = {
loader: 'babel-loader',
options: {
presets: [ __dirname + '/node_modules/babel-preset-es2015' ],
plugins: ['class-display-name']
plugins: [
/**
* Babel transforms some awesome ES6 features to ES5 with extra code, such as Class, JSX.
* This plugin makes all generated extra codes to one module which significantly reduces the bundle code size.
*
* {@link https://github.com/brianZeng/babel-plugin-transform-helper}
*/
['babel-plugin-transform-helper', {
helperFilename:'build/__tmp_babel_helpers.js'
}],
'class-display-name',
]
}
}
},
{
test : /\.js$/,
use: 'eslint-loader?fix=true',
exclude: /node_modules/
exclude: /(node_modules|build)/ // dont need to look in '/build' to prevent analyse __tmp_babel_helper.js
},
{
test: /\.css$/,