mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-08 06:55:26 +02:00
Landing + mobile adoptation
This commit is contained in:
parent
d1e48cbb64
commit
5fbae537c2
26 changed files with 1492 additions and 1038 deletions
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "CodeX Editor 🤩🧦🤨",
|
||||
"title": "Editor.js 🤩🧦🤨",
|
||||
"menu": [
|
||||
"Guides",
|
||||
"API",
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -70,3 +70,4 @@ typings/
|
|||
# Cache of babel and others
|
||||
.cache/
|
||||
.eslintcache
|
||||
.DS_Store
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
"@babel/polyfill": "^7.0.0",
|
||||
"body-parser": "latest",
|
||||
"codex.editor": "^2.1.3",
|
||||
"codex.editor.delimiter": "^1.0.2",
|
||||
"codex.editor.embed": "^2.1.2",
|
||||
"codex.editor.header": "^2.0.5",
|
||||
"codex.editor.image": "^2.0.3",
|
||||
"codex.editor.quote": "^2.1.5",
|
||||
"codex.editor.raw": "^2.0.2",
|
||||
"cookie-parser": "~1.4.3",
|
||||
"debug": "~4.1.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
|
@ -40,8 +45,8 @@
|
|||
"chai": "^4.1.2",
|
||||
"chai-http": "^4.0.0",
|
||||
"codex.editor.code": "^2.0.0",
|
||||
"codex.editor.inline-code": "^1.0.1",
|
||||
"codex.editor.list": "^1.0.2",
|
||||
"codex.editor.inline-code": "^1.2.0",
|
||||
"codex.editor.list": "^1.2.3",
|
||||
"codex.editor.marker": "^1.0.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"css-loader": "^1.0.0",
|
||||
|
|
2
public/dist/code-styling.bundle.js
vendored
2
public/dist/code-styling.bundle.js
vendored
File diff suppressed because one or more lines are too long
63
public/dist/editor.bundle.js
vendored
63
public/dist/editor.bundle.js
vendored
File diff suppressed because one or more lines are too long
4
public/dist/main.bundle.js
vendored
4
public/dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/main.css
vendored
2
public/dist/main.css
vendored
File diff suppressed because one or more lines are too long
|
@ -14,6 +14,7 @@ import ModuleDispatcher from 'module-dispatcher';
|
|||
*/
|
||||
import Writing from './modules/writing';
|
||||
import Page from './modules/page';
|
||||
import Landing from './modules/landing';
|
||||
|
||||
/**
|
||||
* Main app class
|
||||
|
@ -23,14 +24,15 @@ class Docs {
|
|||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
console.log('CodeX Docs initialized');
|
||||
|
||||
this.writing = new Writing();
|
||||
this.page = new Page();
|
||||
this.landing = new Landing();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
this.docReady();
|
||||
});
|
||||
|
||||
console.log('CodeX Docs initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
52
src/frontend/js/classes/cPreview.js
Normal file
52
src/frontend/js/classes/cPreview.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Module to compose output JSON preview
|
||||
*/
|
||||
const cPreview = (function() {
|
||||
/**
|
||||
* Shows JSON in pretty preview
|
||||
* @param {object} output - what to show
|
||||
* @param {Element} holder - where to show
|
||||
*/
|
||||
function show(output, holder) {
|
||||
/** Make JSON pretty */
|
||||
output = JSON.stringify(output, null, 4);
|
||||
/** Encode HTML entities */
|
||||
output = encodeHTMLEntities(output);
|
||||
/** Stylize! */
|
||||
output = stylize(output);
|
||||
holder.innerHTML = output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts '>', '<', '&' symbols to entities
|
||||
*/
|
||||
function encodeHTMLEntities(string) {
|
||||
return string.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Some styling magic
|
||||
*/
|
||||
function stylize(string) {
|
||||
/** Stylize JSON keys */
|
||||
string = string.replace(/"(\w+)"\s?:/g, '"<span class=sc_key>$1</span>" :');
|
||||
/** Stylize tool names */
|
||||
string = string.replace(/"(paragraph|quote|list|header|link|code|image|delimiter|raw|table)"/g, '"<span class=sc_toolname>$1</span>"');
|
||||
/** Stylize HTML tags */
|
||||
string = string.replace(/(<[/a-z]+(>)?)/gi, '<span class=sc_tag>$1</span>');
|
||||
/** Stylize strings */
|
||||
string = string.replace(/"([^"]+)"/gi, '"<span class=sc_attr>$1</span>"');
|
||||
/** Boolean/Null */
|
||||
string = string.replace(/\b(true|false|null)\b/gi, '<span class=sc_bool>$1</span>');
|
||||
|
||||
string = string.replace(/\b(\d+)\b/gi, '<span class=sc_digit>$1</span>');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
return {
|
||||
show
|
||||
};
|
||||
})();
|
||||
|
||||
export default cPreview;
|
|
@ -1,9 +1,18 @@
|
|||
import CodeXEditor from 'codex.editor';
|
||||
import Header from 'codex.editor.header';
|
||||
import CodeTool from 'codex.editor.code';
|
||||
import InlineCode from 'codex.editor.inline-code';
|
||||
import Marker from 'codex.editor.marker';
|
||||
import ListTool from 'codex.editor.list';
|
||||
|
||||
/**
|
||||
* Tools for the Editor
|
||||
*/
|
||||
const Header = require('codex.editor.header');
|
||||
const Quote = require('codex.editor.quote');
|
||||
const Marker = require('codex.editor.marker');
|
||||
const CodeTool = require('codex.editor.code');
|
||||
const Delimiter = require('codex.editor.delimiter');
|
||||
const InlineCode = require('codex.editor.inline-code');
|
||||
const List = require('codex.editor.list');
|
||||
const RawTool = require('codex.editor.raw');
|
||||
const ImageTool = require('codex.editor.image');
|
||||
const Embed = require('codex.editor.embed');
|
||||
|
||||
/**
|
||||
* Class for working with Editor.js
|
||||
|
@ -11,32 +20,59 @@ import ListTool from 'codex.editor.list';
|
|||
export default class Editor {
|
||||
/**
|
||||
* Creates Editor instance
|
||||
* @property {object} initialData - data to start with
|
||||
* @param {object} editorConfig - configuration object for Editor.js
|
||||
* @param {object} data.blocks - data to start with
|
||||
* @param {object} options
|
||||
* @param {string} options.headerPlaceholder - placeholder for Header tool
|
||||
*/
|
||||
constructor({initialData}) {
|
||||
this.editor = new CodeXEditor({
|
||||
constructor(editorConfig = {}, options = {}) {
|
||||
const defaultConfig = {
|
||||
tools: {
|
||||
header: {
|
||||
class: Header,
|
||||
inlineToolbar: ['link', 'marker'],
|
||||
config: {
|
||||
placeholder: 'Enter a title'
|
||||
placeholder: options.headerPlaceholder || ''
|
||||
}
|
||||
},
|
||||
code: CodeTool,
|
||||
// image: {
|
||||
// class: ImageTool,
|
||||
// inlineToolbar: true,
|
||||
// config: {
|
||||
// endpoints: {
|
||||
// byFile: '/editor/transport',
|
||||
// byUrl: '/editor/transport'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
list: {
|
||||
class: List,
|
||||
inlineToolbar: true
|
||||
},
|
||||
quote: {
|
||||
class: Quote,
|
||||
inlineToolbar: true
|
||||
},
|
||||
code: {
|
||||
class: CodeTool,
|
||||
shortcut: 'CMD+SHIFT+D'
|
||||
},
|
||||
inlineCode: {
|
||||
class: InlineCode,
|
||||
shortcut: 'CMD+SHIFT+I'
|
||||
shortcut: 'CMD+SHIFT+C'
|
||||
},
|
||||
Marker: {
|
||||
rawTool: {
|
||||
class: RawTool,
|
||||
shortcut: 'CMD+SHIFT+R'
|
||||
},
|
||||
marker: {
|
||||
class: Marker,
|
||||
shortcut: 'CMD+SHIFT+M'
|
||||
},
|
||||
list: {
|
||||
class: ListTool,
|
||||
inlineToolbar: true
|
||||
}
|
||||
delimiter: Delimiter,
|
||||
embed: Embed
|
||||
},
|
||||
data: initialData || {
|
||||
data: {
|
||||
blocks: [
|
||||
{
|
||||
type: 'header',
|
||||
|
@ -47,7 +83,9 @@ export default class Editor {
|
|||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.editor = new CodeXEditor(Object.assign(defaultConfig, editorConfig));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,4 +95,11 @@ export default class Editor {
|
|||
save() {
|
||||
return this.editor.saver.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on Editor's node to focus after Editor has loaded
|
||||
*/
|
||||
focus() {
|
||||
document.querySelector('.codex-editor__redactor').click();
|
||||
}
|
||||
}
|
||||
|
|
90
src/frontend/js/modules/landing.js
Normal file
90
src/frontend/js/modules/landing.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Module to compose output JSON preview
|
||||
*/
|
||||
const {default: cPreview} = require('../classes/cPreview');
|
||||
|
||||
/**
|
||||
* Module for pages using Editor
|
||||
*/
|
||||
export default class Landing {
|
||||
constructor() {
|
||||
/**
|
||||
* Editor class Instance
|
||||
*/
|
||||
this.editor = null;
|
||||
|
||||
/**
|
||||
* DOM elements
|
||||
*/
|
||||
this.nodes = {
|
||||
/**
|
||||
* Container to output saved Editor data
|
||||
*/
|
||||
outputWrapper: null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} editorLandingSettings - Editor landing class settings
|
||||
* @property {String} editorLandingSettings.output_id - ID of container where Editor's saved data will be shown
|
||||
* @property {function} editorLandingSettings.onChange - Modifications callback for the Editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialization. Called by Module Dispatcher
|
||||
*/
|
||||
init(editorLandingSettings) {
|
||||
/**
|
||||
* Prepare node to output Editor data preview
|
||||
* @type {HTMLElement} - JSON preview container
|
||||
*/
|
||||
this.nodes.outputWrapper = document.getElementById(editorLandingSettings.output_id);
|
||||
|
||||
if (!this.nodes.outputWrapper) {
|
||||
console.warn('Can\'t find output target with ID: «' + editorLandingSettings.output_id + '»');
|
||||
}
|
||||
|
||||
this.loadEditor({
|
||||
data: {
|
||||
blocks: editorLandingSettings.blocks
|
||||
},
|
||||
/**
|
||||
* Bind onchange callback to preview JSON data
|
||||
*/
|
||||
onChange: () => {
|
||||
this.previewData();
|
||||
},
|
||||
/**
|
||||
* When Editor is ready, preview JSON output with initial data
|
||||
*/
|
||||
onReady: () => {
|
||||
this.previewData();
|
||||
this.editor.focus();
|
||||
}
|
||||
}).then((editor) => {
|
||||
this.editor = editor;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load Editor from separate chunk
|
||||
* @param settings - settings for Editor initialization
|
||||
* @return {Promise<Editor>} - CodeX Editor promise
|
||||
*/
|
||||
async loadEditor(settings) {
|
||||
const {default: Editor} = await import(/* webpackChunkName: "editor" */ './../classes/editor');
|
||||
|
||||
return new Editor(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows JSON output of editor saved data
|
||||
*/
|
||||
previewData() {
|
||||
this.editor.save().then((savedData) => {
|
||||
cPreview.show(savedData, this.nodes.outputWrapper);
|
||||
});
|
||||
};
|
||||
};
|
|
@ -66,7 +66,7 @@ export default class Writing {
|
|||
this.nodes.removeButton.addEventListener('click', () => {
|
||||
const isUserAgree = confirm("Are you sure?");
|
||||
if (!isUserAgree) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeButtonClicked();
|
||||
|
@ -85,8 +85,12 @@ export default class Writing {
|
|||
async loadEditor() {
|
||||
const {default: Editor} = await import(/* webpackChunkName: "editor" */ './../classes/editor');
|
||||
|
||||
return new Editor({
|
||||
initialData: this.page ? this.page.body : null
|
||||
const editorConfig = this.page ? {
|
||||
data: this.page.body
|
||||
} : {};
|
||||
|
||||
return new Editor(editorConfig, {
|
||||
headerPlaceholder: 'Enter a title'
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,16 @@
|
|||
font-size: 15px;
|
||||
color: var(--color-text-second);
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 13px;
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&--toggled {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -9,9 +19,21 @@
|
|||
&__section {
|
||||
margin-bottom: 30px;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: 15px;
|
||||
color: var(--color-link-active);
|
||||
|
||||
@media (--mobile) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&-list {
|
||||
|
@ -26,3 +48,18 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.docs-aside-toggler {
|
||||
display: none;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
color: var(--color-text-second);
|
||||
|
||||
@media (--mobile) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
border-bottom: 1px solid var(--color-line-gray);
|
||||
font-size: 15.8px;
|
||||
line-height: 50px;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
|
@ -18,10 +20,38 @@
|
|||
&__menu {
|
||||
display: flex;
|
||||
margin: 0 0 0 auto;
|
||||
padding-left: 0;
|
||||
|
||||
@media (--mobile) {
|
||||
flex-basis: 100%;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
margin-left: 20px;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-left: 0;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&-add {
|
||||
@media (--mobile) {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 15px;
|
||||
line-height: 1em;
|
||||
margin: 0 !important;
|
||||
}
|
||||
a {
|
||||
@media (--mobile) {
|
||||
font-size: 0;
|
||||
padding: 8px;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a:not(.docs-header__button) {
|
||||
|
|
670
src/frontend/styles/components/landing.pcss
Normal file
670
src/frontend/styles/components/landing.pcss
Normal file
|
@ -0,0 +1,670 @@
|
|||
/**
|
||||
* Editor landing page
|
||||
*/
|
||||
.editor-landing {
|
||||
width: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
position: relative;
|
||||
content: '';
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
margin: auto;
|
||||
|
||||
@media (--mobile) {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
&-main {
|
||||
position: absolute;
|
||||
animation: logoIn 1 500ms cubic-bezier(0.5, 1.05, 1, 1);
|
||||
animation-fill-mode: forwards;
|
||||
will-change: transform, filter;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
|
||||
@media (--mobile) {
|
||||
svg {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-shadow {
|
||||
position: absolute;
|
||||
left: -38px;
|
||||
z-index: 1;
|
||||
animation: logoShadow 1 500ms cubic-bezier(0.5, 1.05, 1, 1);
|
||||
animation-fill-mode: forwards;
|
||||
will-change: transform, opacity;
|
||||
|
||||
@media (--mobile) {
|
||||
left: -21px;
|
||||
margin-top: -13px;
|
||||
|
||||
svg {
|
||||
width: 92px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor title and description block
|
||||
*/
|
||||
&__info {
|
||||
padding-top: 300px;
|
||||
padding-bottom: 70px;
|
||||
background-image: linear-gradient(0deg, #FFFFFF 0%, #EEF7FF 100%);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin: 20px 0 0;
|
||||
line-height: 1.2em;
|
||||
font-size: 50px;
|
||||
letter-spacing: 0.23px;
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-top: 25px;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: 17.3px;
|
||||
letter-spacing: 0.13px;
|
||||
line-height: 1.5em;
|
||||
color: #868DA1;
|
||||
margin-top: 20px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 15px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&__cta {
|
||||
display: inline-block;
|
||||
margin-top: 40px;
|
||||
padding: 13px 19px;
|
||||
border-radius: 30px;
|
||||
background: #388ffe;
|
||||
box-shadow: 0 9px 12px -6px rgba(11,132,242,0.78);
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
transition: all 150ms ease;
|
||||
will-change: background-color, box-shadow;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background: #3684fe;
|
||||
box-shadow: 0 9px 16px -6px rgba(11,132,242,0.78);
|
||||
}
|
||||
}
|
||||
|
||||
&__menu {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
position: fixed;
|
||||
right: 7vw;
|
||||
top: 150px;
|
||||
|
||||
@media (max-width: 1400px) {
|
||||
right: 4.5vw;
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 1330px) {
|
||||
position: absolute;
|
||||
padding: 20px;
|
||||
right: 45px;
|
||||
top: 55px;
|
||||
}
|
||||
|
||||
|
||||
@media (--mobile) {
|
||||
position: absolute;
|
||||
padding: 20px;
|
||||
left: 0;
|
||||
top: 45px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
display: inline-block;
|
||||
border-bottom: 1px solid rgba(93,100,134,0.20);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&__version {
|
||||
display: inline-block;
|
||||
padding: 5px 8px;
|
||||
line-height: 1em;
|
||||
border-radius: 30px;
|
||||
background: #111111;
|
||||
font-size: 10px;
|
||||
color: #FFFFFF;
|
||||
margin-right: -70px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
&__demo {
|
||||
background: #eef5fa;
|
||||
border-radius: 100px;
|
||||
max-width: 950px;
|
||||
margin: 0 auto;
|
||||
padding: 70px 60px;
|
||||
|
||||
@media (max-width: 1550px) {
|
||||
max-width: 850px;
|
||||
}
|
||||
|
||||
@media (--mobile) {
|
||||
padding: 15px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 24px 24px -18px rgba(69,104,129,0.33), 0 9px 45px 0 rgba(114,119,160,0.12);
|
||||
padding: 70px 50px;
|
||||
font-size: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@media (--mobile) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&-inner,
|
||||
.codex-editor__redactor {
|
||||
min-height: 450px;
|
||||
|
||||
@media (--mobile) {
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__preview {
|
||||
max-width: var(--layout-width-main-col);
|
||||
margin: 0 auto;
|
||||
color: rgba(34, 78, 111, 0.75);
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 150px;
|
||||
background: linear-gradient(90deg, rgba(238, 245, 250, 0), #eef5fa);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
overflow: auto;
|
||||
font-size: 14px;
|
||||
line-height: 1.5em;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
}
|
||||
|
||||
&__section-header {
|
||||
font-size: 16px;
|
||||
max-width: 375px;
|
||||
margin: 50px auto;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
color: #606578;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 14px;
|
||||
max-width: 70vw;
|
||||
}
|
||||
|
||||
header {
|
||||
font-weight: 600;
|
||||
margin-bottom: 13px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&--big {
|
||||
margin: 130px auto;
|
||||
line-height: 24px;
|
||||
|
||||
@media (--mobile) {
|
||||
margin: 50px auto;
|
||||
}
|
||||
|
||||
header {
|
||||
font-size: 26px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* JSON output code highlighting
|
||||
*/
|
||||
.sc_attr {
|
||||
color: #373742;
|
||||
}
|
||||
|
||||
.sc_toolname {
|
||||
color: #db1029;
|
||||
}
|
||||
|
||||
.sc_tag {
|
||||
color: rgb(4, 131, 216);
|
||||
}
|
||||
|
||||
.sc_key {
|
||||
color: #6e4998;
|
||||
}
|
||||
|
||||
.sc_bool {
|
||||
color: rgb(247, 60, 173);
|
||||
}
|
||||
|
||||
.sc_digit {
|
||||
color: #196ff8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loved by section
|
||||
*/
|
||||
&__loved-by {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 30px;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
|
||||
&:not(:last-of-type)::after {
|
||||
content: '';
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
margin-right: 27px;
|
||||
margin-left: 29px;
|
||||
background: #e0e0e0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Best plugins section
|
||||
*/
|
||||
&__plugins {
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (--mobile) {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 24px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
margin-bottom: 30px;
|
||||
font-size: 16px;
|
||||
line-height: 1.65em;
|
||||
color: #606578;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&-filter {
|
||||
margin: 30px 0;
|
||||
|
||||
@media (--mobile) {
|
||||
margin: 15px 0 20px;
|
||||
}
|
||||
|
||||
&-button {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #343434;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
margin: -3px 6px 0 3px;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Links at the bottom of plugins list
|
||||
*/
|
||||
&__more-plugins,
|
||||
&__contribute {
|
||||
font-size: 15px;
|
||||
color: #7b7e89;
|
||||
cursor: pointer;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
fill: currentColor;
|
||||
vertical-align: middle;
|
||||
|
||||
@media (--mobile) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__more-plugins {
|
||||
float: left;
|
||||
|
||||
@media (--mobile) {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__contribute {
|
||||
float: right;
|
||||
|
||||
@media (--mobile) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
svg {
|
||||
margin: -3px 3px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default editor's padding-bottom
|
||||
*/
|
||||
.codex-editor__redactor {
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
&__star {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-top: 60px;
|
||||
|
||||
&-line {
|
||||
position: absolute;
|
||||
width: 130px;
|
||||
height: 10px;
|
||||
left: 51.5%;
|
||||
top: 36%;
|
||||
z-index: -1;
|
||||
|
||||
&:nth-of-type(1){
|
||||
transform: translateX(-50%) rotate(-22deg);
|
||||
}
|
||||
|
||||
&:nth-of-type(2){
|
||||
transform: rotate(-90deg) ;
|
||||
left: -11px;
|
||||
top: 13px;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
&:nth-of-type(3){
|
||||
transform: translateX(-50%) rotate(22deg);
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 10px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='15' height='10' viewBox='0 0 15 10' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 5.5H0v-1h6v-4L15 5 6 9.5z' fill='%23B6B9C0' fill-rule='nonzero'/%3E%3C/svg%3E");
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: 0;
|
||||
animation: arrow-moving-left infinite 1000ms ease;
|
||||
}
|
||||
|
||||
&:after{
|
||||
right: 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='15' height='10' viewBox='0 0 15 10' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9 4.5h6v1H9v4L0 5 9 .5v4z' fill='%23B6B9C0' fill-rule='nonzero'/%3E%3C/svg%3E");
|
||||
animation: arrow-moving-right infinite 1000ms ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes arrow-moving-left {
|
||||
50% {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes arrow-moving-right {
|
||||
50% {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin items styles
|
||||
*/
|
||||
.editor-plugin {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 7px;
|
||||
box-shadow: 0 3px 11px rgba(125, 128, 147, 0.23);
|
||||
min-height: 90px;
|
||||
padding-right: 120px;
|
||||
|
||||
@media (--mobile) {
|
||||
padding-right: 100px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
margin-bottom: 4px;
|
||||
margin-right: 5px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: inline-block;
|
||||
font-size: 18px;
|
||||
color: #606578;
|
||||
border-radius: 3px;
|
||||
font-weight: 500;
|
||||
opacity: 0.4;
|
||||
line-height: 1em;
|
||||
margin-top: -5px;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: 14px;
|
||||
color: #606578;
|
||||
}
|
||||
|
||||
&__contributors {
|
||||
display: flex;
|
||||
margin-top: auto;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
&-item {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__demo {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 15px;
|
||||
margin-left: 45px;
|
||||
|
||||
img,
|
||||
video {
|
||||
height: 90px;
|
||||
|
||||
@media (--mobile) {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--your-own {
|
||||
^&__title {
|
||||
color: #7b7e89;
|
||||
}
|
||||
|
||||
^&__description {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
^&__demo {
|
||||
position: static;
|
||||
margin-left: 0;
|
||||
|
||||
pre {
|
||||
font-size: 12px;
|
||||
line-height: 2em;
|
||||
font-family: Menlo, Monaco, Consolas, Courier New, monospace;
|
||||
margin: 15px 0;
|
||||
font-weight: 500;
|
||||
color: #484554;
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
^&__footer {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes logoIn {
|
||||
0% {
|
||||
transform: translateY(-80px) scale(1, 1.3 );
|
||||
filter: blur(4px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translateY(5px) scale(1, 0.92);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: translateY(0) scale(1)
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes logoShadow {
|
||||
0% {
|
||||
transform: scale(1.6, 0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(0.8, 0.8) translateY(-10px);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-10px);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,10 +6,18 @@
|
|||
display: flex;
|
||||
color: var(--color-text-second);
|
||||
|
||||
@media (--mobile) {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&-nav {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
@media (--mobile) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--color-link-active);
|
||||
}
|
||||
|
@ -24,6 +32,10 @@
|
|||
|
||||
&-time {
|
||||
margin-left: auto;
|
||||
|
||||
@media (--mobile) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-button {
|
||||
|
|
|
@ -2,14 +2,31 @@
|
|||
display: flex;
|
||||
padding: 0 var(--layout-padding-horisontal);
|
||||
|
||||
@media (--mobile) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__aside {
|
||||
width: var(--layout-width-aside);
|
||||
|
||||
@media (--mobile) {
|
||||
width: 100%;
|
||||
flex-basis: 100%;
|
||||
padding: 20px var(--layout-padding-horisontal) !important;
|
||||
margin: 0 calc(-1 * var(--layout-padding-horisontal));
|
||||
border-bottom: 1px solid var(--color-line-gray);
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
flex-grow: 2;
|
||||
word-wrap: break-word;
|
||||
|
||||
@media (--mobile) {
|
||||
width: 100%;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
max-width: var(--layout-width-main-col);
|
||||
margin: 0 auto;
|
||||
|
@ -19,5 +36,9 @@
|
|||
&__aside,
|
||||
&__content {
|
||||
padding: var(--layout-padding-vertical) 0;
|
||||
|
||||
@media (--mobile) {
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
@import url('components/aside.pcss');
|
||||
@import url('components/writing.pcss');
|
||||
@import url('components/page.pcss');
|
||||
@import url('components/landing.pcss');
|
||||
|
||||
body {
|
||||
font-family: system-ui, Helvetica, Arial, Verdana;
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
--layout-width-aside: 200px;
|
||||
--layout-width-main-col: 650px;
|
||||
|
||||
@media (--mobile) {
|
||||
--layout-padding-horisontal: 15px;
|
||||
--layout-padding-vertical: 15px;
|
||||
}
|
||||
|
||||
--button {
|
||||
display: inline-block;
|
||||
padding: 9px 15px;
|
||||
|
@ -25,6 +30,7 @@
|
|||
line-height: 1em;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
|
||||
svg {
|
||||
margin: 0 0.3em 0 -0.05em;
|
||||
|
@ -51,3 +57,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom media queries
|
||||
*/
|
||||
@custom-media --desktop all and (min-width: 1050px);
|
||||
@custom-media --tablet all and (max-width: 1050px);
|
||||
@custom-media --mobile all and (max-width: 980px);
|
||||
@custom-media --retina all and (-webkit-min-device-pixel-ratio: 1.5);
|
||||
|
|
1
src/frontend/svg/menu.svg
Normal file
1
src/frontend/svg/menu.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="13" height="10" viewBox="0 0 13 10" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h13v2H0V0zm0 4h13v2H0V4zm0 4h13v2H0V8z" fill-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 164 B |
|
@ -3,7 +3,199 @@ const router = express.Router();
|
|||
|
||||
/* GET home page. */
|
||||
router.get('/', function (req, res, next) {
|
||||
res.render('index', { title: 'Express' });
|
||||
/**
|
||||
* Array of plugins contributors
|
||||
*/
|
||||
var contributors = {
|
||||
polinaShneider: {
|
||||
name: 'PolinaShneider',
|
||||
photo: 'https://avatars3.githubusercontent.com/u/15448200?s=40&v=4'
|
||||
},
|
||||
specc: {
|
||||
name: 'neSpecc',
|
||||
photo: 'https://avatars0.githubusercontent.com/u/3684889?v=4&s=40'
|
||||
},
|
||||
n0str: {
|
||||
name: 'n0str',
|
||||
photo: 'https://avatars1.githubusercontent.com/u/988885?v=4&s=60'
|
||||
},
|
||||
talyguryn: {
|
||||
name: 'talyguryn',
|
||||
photo: 'https://avatars1.githubusercontent.com/u/15259299?v=4&s=40'
|
||||
},
|
||||
khaydarov: {
|
||||
name: 'khaydarov',
|
||||
photo: 'https://avatars1.githubusercontent.com/u/6507765?s=40&v=4'
|
||||
},
|
||||
horoyami: {
|
||||
name: 'horoyami',
|
||||
photo: 'https://avatars2.githubusercontent.com/u/34141926?s=40&v=4'
|
||||
},
|
||||
gohabereg: {
|
||||
name: 'gohabereg',
|
||||
photo: 'https://avatars1.githubusercontent.com/u/23050529?s=40&v=4'
|
||||
}
|
||||
};
|
||||
|
||||
var plugins = [
|
||||
{
|
||||
name: 'Header',
|
||||
type: 'Block',
|
||||
description: 'How will you live without headers?',
|
||||
demo: '/public/app/landings/editor/demo/header.png',
|
||||
url: 'https://github.com/codex-editor/header',
|
||||
contributors: [
|
||||
contributors['specc'],
|
||||
contributors['talyguryn'],
|
||||
contributors['n0str']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Simple Image',
|
||||
type: 'Block',
|
||||
description: 'Allow pasting image by URLs',
|
||||
demo: 'https://capella.pics/f67bd749-0115-4ea8-b4b9-4375b20667bc.jpg',
|
||||
url: 'https://github.com/codex-editor/simple-image',
|
||||
contributors: [
|
||||
contributors['specc']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Image',
|
||||
type: 'Block',
|
||||
description: 'Full featured image Block integrated with your backend',
|
||||
demo: '/public/app/landings/editor/demo/image-tool.mp4',
|
||||
url: 'https://github.com/codex-editor/image',
|
||||
contributors: [
|
||||
contributors['specc'],
|
||||
contributors['talyguryn']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Embed',
|
||||
type: 'Block',
|
||||
description: 'Here is YouTube, Vimeo, Imgur, Gfycat, Twitch and other embeds',
|
||||
demo: '/public/app/landings/editor/demo/embed.mp4',
|
||||
url: 'https://github.com/codex-editor/embed',
|
||||
contributors: [
|
||||
contributors['gohabereg']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Quote',
|
||||
type: 'Block',
|
||||
description: 'Include quotes in your articles',
|
||||
demo: '/public/app/landings/editor/demo/quote.png',
|
||||
url: 'https://github.com/codex-editor/quote',
|
||||
contributors: [
|
||||
contributors['talyguryn']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Marker',
|
||||
type: 'Inline Tool',
|
||||
description: 'Highlight text fragments in your beautiful articles',
|
||||
demo: '/public/app/landings/editor/demo/marker.gif',
|
||||
url: 'https://github.com/codex-editor/marker',
|
||||
contributors: [
|
||||
contributors['polinaShneider']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Code',
|
||||
type: 'Block',
|
||||
description: 'Include code examples in your writings',
|
||||
demo: 'https://capella.pics/8c48b0e0-4885-452d-9a78-d563d279d08d.jpg',
|
||||
url: 'https://github.com/codex-editor/code',
|
||||
contributors: [
|
||||
contributors['talyguryn'],
|
||||
contributors['polinaShneider']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Link',
|
||||
type: 'Inline Tool',
|
||||
description: 'Embed links in your articles',
|
||||
demo: '/public/app/landings/editor/demo/link.gif',
|
||||
url: 'https://github.com/codex-editor/link',
|
||||
contributors: [
|
||||
contributors['specc'],
|
||||
contributors['talyguryn'],
|
||||
contributors['khaydarov']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'List',
|
||||
type: 'Block',
|
||||
description: 'Add ordered or bullet lists to your article',
|
||||
demo: '/public/app/landings/editor/demo/list.png',
|
||||
url: 'https://github.com/codex-editor/list',
|
||||
contributors: [
|
||||
contributors['specc'],
|
||||
contributors['talyguryn'],
|
||||
contributors['khaydarov']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Delimiter',
|
||||
type: 'Block',
|
||||
description: 'Separate blocks of text in your articles',
|
||||
demo: 'https://capella.pics/825a3f47-ef7e-4c64-bc73-521c9c3faee4.jpg',
|
||||
url: 'https://github.com/codex-editor/delimiter',
|
||||
contributors: [
|
||||
contributors['n0str'],
|
||||
contributors['talyguryn'],
|
||||
contributors['specc']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Inline Code',
|
||||
type: 'Inline Tool',
|
||||
description: 'Inline Tool for marking code-fragments',
|
||||
demo: '/public/app/landings/editor/demo/inline-code.gif',
|
||||
url: 'https://github.com/codex-editor/inline-code',
|
||||
contributors: [
|
||||
contributors['talyguryn']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'HTML',
|
||||
type: 'Block',
|
||||
description: 'Include raw HTML code in your articles',
|
||||
demo: 'https://capella.pics/7cf636b6-dad4-4798-bfa4-5273e6c0250f.jpg',
|
||||
url: 'https://github.com/codex-editor/raw',
|
||||
contributors: [
|
||||
contributors['talyguryn'],
|
||||
contributors['polinaShneider']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Warning',
|
||||
type: 'Block',
|
||||
description: 'Editorial notifications, appeals or warnings',
|
||||
demo: 'https://capella.pics/ff210390-4b0b-4655-aaf0-cc4a0414e81b.jpg',
|
||||
url: 'https://github.com/codex-editor/warning',
|
||||
contributors: [
|
||||
contributors['polinaShneider'],
|
||||
contributors['specc']
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Table',
|
||||
type: 'Block',
|
||||
description: 'Table constructor that you would enjoy',
|
||||
demo: '/public/app/landings/editor/demo/table.mp4',
|
||||
url: 'https://github.com/codex-editor/table',
|
||||
contributors: [
|
||||
contributors['horoyami'],
|
||||
contributors['gohabereg']
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
res.render('index', {
|
||||
plugins
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<div class="docs-aside-toggler" onclick="document.querySelector('.docs-aside').classList.toggle('docs-aside--toggled')">
|
||||
{{ svg('menu') }} Table of contents
|
||||
</div>
|
||||
<div class="docs-aside">
|
||||
{% for firstLevelPage in menu %}
|
||||
<section class="docs-aside__section">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{{ config.title }}
|
||||
</a>
|
||||
<ul class="docs-header__menu">
|
||||
<li>
|
||||
<li class="docs-header__menu-add">
|
||||
<a class="docs-header__button" href="/page/new">
|
||||
{{ svg('plus') }}
|
||||
Add Page
|
||||
|
|
|
@ -1,6 +1,199 @@
|
|||
{% extends 'layout.twig' %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ config.title }}</title>
|
||||
<link rel="stylesheet" href="/dist/main.css" />
|
||||
</head>
|
||||
<body>
|
||||
{% include "components/header.twig" %}
|
||||
<div class="editor-landing">
|
||||
<div class="editor-landing__info">
|
||||
<div class="editor-landing__logo">
|
||||
<span class="editor-landing__logo-main">
|
||||
<svg width="84" height="84" viewBox="0 0 84 84" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="editorjs-logo-a"><stop stop-color="#39FFD7" offset="0%"/><stop stop-color="#308EFF" offset="100%"/></linearGradient></defs><g fill-rule="nonzero" fill="none"><circle fill="url(#editorjs-logo-a)" cx="42" cy="42" r="42"/><rect fill="#FFF" x="38" y="17" width="8" height="50" rx="4"/><rect fill="#FFF" x="17" y="38" width="50" height="8" rx="4"/></g></svg>
|
||||
</span>
|
||||
<span class="editor-landing__logo-shadow">
|
||||
<svg width="158" height="160" viewBox="0 0 158 160" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="10.449%" x2="50%" y2="91.174%" id="edjls-a"><stop stop-color="#217DE9" stop-opacity=".919" offset="0%"/><stop stop-color="#308EFF" offset="100%"/></linearGradient><filter x="-81.4%" y="-81.4%" width="262.9%" height="262.9%" filterUnits="objectBoundingBox" id="edjls-b"><feGaussianBlur stdDeviation="19" in="SourceGraphic"/></filter></defs><circle filter="url(#edjls-b)" cx="163" cy="116" r="35" transform="translate(-84 -37)" fill="url(#edjls-a)" fill-rule="nonzero"/></svg>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 class="editor-landing__title">
|
||||
Editor.js
|
||||
</h1>
|
||||
<div class="editor-landing__description">
|
||||
Next generation block styled editor. <br> Free. Use for pleasure.
|
||||
</div>
|
||||
|
||||
<a class="editor-landing__cta" href="http://github.com/codex-team/codex.editor">
|
||||
Get started
|
||||
</a>
|
||||
|
||||
<div class="editor-landing__menu">
|
||||
<a href="http://github.com/codex-team/codex.editor">
|
||||
Current version
|
||||
<span class="editor-landing__version">
|
||||
?.?.?
|
||||
</span>
|
||||
</a>
|
||||
<br>
|
||||
<a class="editor-landing__links-item" target="_blank" href="https://github.com/codex-team/codex.editor/blob/master/docs/usage.md">
|
||||
Documentation
|
||||
</a>
|
||||
<br>
|
||||
<a class="editor-landing__links-item" target="_blank" href="https://github.com/codex-editor">
|
||||
Plugins
|
||||
</a>
|
||||
<br>
|
||||
<a class="editor-landing__links-item" target="_blank" href="https://github.com/codex-editor">
|
||||
Changelog
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-landing__demo" data-module="landing">
|
||||
<module-settings hidden>
|
||||
{
|
||||
"output_id" : "output",
|
||||
"blocks" : []
|
||||
}
|
||||
</module-settings>
|
||||
|
||||
<div class="editor-landing__demo-inner">
|
||||
<div id="codex-editor"></div>
|
||||
</div>
|
||||
|
||||
<section class="editor-landing__section-header">
|
||||
<header>
|
||||
And here is a generated CLEAN data
|
||||
</header>
|
||||
Use it in Web, mobile, APM, Instant Articles, speech readers — everywhere. Easy to sanitize, extend and integrate with your logic.
|
||||
</section>
|
||||
<div class="editor-landing__preview">
|
||||
<div class="editor-landing__preview-inner">
|
||||
<pre id="output"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="editor-landing__section-header editor-landing__section-header--big">
|
||||
<header>
|
||||
API is the feature.
|
||||
</header>
|
||||
Each Block provided by plugin. It's really easy to create your own. Dozens of created.
|
||||
</section>
|
||||
|
||||
<div class="editor-landing__plugins">
|
||||
<h4 class="editor-landing__plugins-title">
|
||||
Best plugins
|
||||
</h4>
|
||||
<div class="editor-landing__plugins-description">
|
||||
Plugins can represent any Blocks: Quotes, Galleries, Polls, Embeds, Tables — anything you need. Also they can implement Inline Tools such as Marker, Term, Comments etc.
|
||||
</div>
|
||||
|
||||
{% for plugin in plugins %}
|
||||
<div class="editor-plugin clearfix">
|
||||
<div class="editor-plugin__demo">
|
||||
{% if 'mp4' in plugin.demo %}
|
||||
<video autoplay loop muted playsinline>
|
||||
<source src="{{ plugin.demo }}" type="video/mp4">
|
||||
</video>
|
||||
{% else %}
|
||||
<img src="{{ plugin.demo }}" alt="{{ plugin.name }} Tool for Editor.js">
|
||||
{% endif %}
|
||||
</div>
|
||||
<a href="{{ plugin.url }}" target="_blank">
|
||||
<h3 class="editor-plugin__title">
|
||||
{{ plugin.name }}
|
||||
</h3>
|
||||
<span class="editor-plugin__label">
|
||||
{{ plugin.type }}
|
||||
</span>
|
||||
</a>
|
||||
<div class="editor-plugin__description">
|
||||
{{ plugin.description }}
|
||||
</div>
|
||||
<div class="editor-plugin__contributors">
|
||||
{% for user in plugin.contributors %}
|
||||
<a href="https://github.com/{{ user.name }}" class="editor-plugin__contributors-item" title="{{ user.name }}" target="_blank">
|
||||
<img src="{{ user.photo }}" alt="{{ user.name }}">
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%
|
||||
set ownTool = "<span style='color:#b83370'>class</span> <span style='color:#8c74b2'>MyTool</span> {
|
||||
render() {
|
||||
<span style='color:#b83370'>return</span> document.createElement(’textarea’);
|
||||
}
|
||||
save(textarea) {
|
||||
<span style='color:#b83370;'>return</span> {
|
||||
text: textarea.value
|
||||
}
|
||||
}
|
||||
}"
|
||||
%}
|
||||
<div class="editor-plugin editor-plugin--your-own">
|
||||
<h3 class="editor-plugin__title">
|
||||
Your own plugin
|
||||
</h3>
|
||||
<div class="editor-plugin__description">
|
||||
Just implement <i>render</i> and <i>save</i> methods.
|
||||
</div>
|
||||
<div class="editor-plugin__demo">
|
||||
<pre>{{ ownTool }}</pre>
|
||||
</div>
|
||||
<div class="editor-plugin__footer">
|
||||
To make it cool, take a look at the <a href="https://github.com/codex-team/codex.editor/blob/master/docs/tools.md">API</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-landing__actions clearfix">
|
||||
<a class="editor-landing__more-plugins" href="https://github.com/codex-editor" target="_blank">
|
||||
View all plugins
|
||||
</a>
|
||||
<a class="editor-landing__contribute" href="#">
|
||||
<? include(DOCROOT . '/public/app/landings/editor/svg/plus-icon.svg'); ?>
|
||||
Contribute your plugin to this featured list
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="editor-landing__section-header editor-landing__section-header--big">
|
||||
<header>
|
||||
Loved by
|
||||
</header>
|
||||
Thousands of people already write with us.
|
||||
<div class="editor-landing__loved-by">
|
||||
<a rel="nofollow" class="editor-landing__loved-by-item" target="_blank" href="//tjournal.ru">
|
||||
<svg width="27" height="28"><g fill-rule="nonzero" fill="none"><path fill="#3A3A3B" opacity=".5" d="M0 21.28h9.52V28H0z"/><path fill="#3A3A3B" d="M0 7.84h9.52V28l7.28-6.72V7.84h10.08V0H0z"/><path fill="#51535A" opacity=".604" d="M8.4 21.28h1.12V28z"/></g></svg>
|
||||
</a>
|
||||
<a rel="nofollow" class="editor-landing__loved-by-item" target="_blank" href="//dtf.ru">
|
||||
<svg width="74" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.074 0H0v24h15.074c5.232 0 9.486-4.157 9.486-9.27V9.27C24.561 4.156 20.306 0 15.074 0zm3.309 14.73c0 1.783-1.483 3.235-3.308 3.235h-8.9V6.035h8.9c1.823 0 3.307 1.448 3.307 3.234v5.462h.001zm7.921-8.696h8.623V23.95h6.176V6.034h8.623V0H26.304v6.034zm46.74 0V0H53.101v23.95h6.175v-7.056h10.416v-6.031H59.277V6.034h13.766z" fill-rule="nonzero" fill="#51535A"/></svg>
|
||||
</a>
|
||||
<a rel="nofollow" class="editor-landing__loved-by-item" target="_blank" href="//vc.ru">
|
||||
<svg width="31" height="29" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="#3A3A3B"><path d="M24.086 12.999c2.225 0 3.9-.932 5.135-2.556l-1.652-1.27a4.343 4.343 0 0 1-3.483 1.735c-2.416 0-4.16-1.977-4.16-4.408s1.72-4.52 4.233-4.52c1.115 0 1.906.263 2.595.694v2.137h2.078V1.697l-.398-.314C27.288.478 25.545 0 24.086 0c-3.562 0-6.46 2.916-6.46 6.5 0 3.583 2.898 6.499 6.46 6.499zM28.398 25.827l-.073-2.994v-7.307h-4.333v2.092h2.145v4.954c0 2.137-1.623 3.647-3.257 3.647-1.635 0-2.488-1.141-2.488-3.278v-7.415h-4.048v2.092h1.86v5.692c0 2.896 1.614 4.89 4.492 4.89 1.653 0 2.915-.92 3.667-2.348h.033l.297 1.992h3.327v-2.017h-1.622zM17.146.306H13.54l-3.14 9.174h-.049L7.226.306H3.379v2.091H5.54l3.724 10.457h1.98v-.002.001l3.881-10.456h2.021zM0 27.91h2.137v-2.15H0zM8.26 17.95h-.024L8.1 15.527H4.28v1.907h2.035v8.393H4.282v2.018h9.436v-1.981h-5.25v-5.067c.236-1.833 1.603-3.4 3.466-3.4h.034l-.035 1.874h2.078v-3.785h-1.64c-1.884 0-3.28 1.025-4.11 2.466z"/></g></svg>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="editor-landing__section-header editor-landing__section-header--big">
|
||||
<header>
|
||||
Support Team
|
||||
</header>
|
||||
We will be really glad and inspired by <b>every</b> star of the project. It helps community to grow, build new cool plugins and core features.
|
||||
|
||||
<br>
|
||||
<div class="editor-landing__star">
|
||||
<div class="editor-landing__star-line"></div>
|
||||
<div class="editor-landing__star-line"></div>
|
||||
<div class="editor-landing__star-line"></div>
|
||||
|
||||
<a class="github-button" href="https://github.com/codex-team/codex.editor" data-icon="octicon-star" data-size="large" aria-label="Star codex-team/codex.editor on GitHub">Star</a>
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script src="/dist/main.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{% block body %}
|
||||
{{title}}
|
||||
<p>Welcome to {{title}}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
<title>{{ config.title }}</title>
|
||||
<link rel="stylesheet" href="/dist/main.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue