mirror of
https://github.com/codex-team/editor.js
synced 2024-05-20 15:26:48 +02:00
cover restoring and fetch function fixed (#101)
* cover restoring fixed * upd * fetch fixed in safari * updated * plugins * plugins ready * code improved * fixed bug with backspace * improved architecture
This commit is contained in:
parent
b76ec5c0a1
commit
bc8fb1aed9
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,5 +5,4 @@ Thumbs.db
|
||||||
/*.sublime-project
|
/*.sublime-project
|
||||||
/*.sublime-workspace
|
/*.sublime-workspace
|
||||||
|
|
||||||
node_modules/*
|
node_modules/*
|
||||||
plugins/*
|
|
|
@ -60,6 +60,7 @@
|
||||||
* Plus button
|
* Plus button
|
||||||
*/
|
*/
|
||||||
.ce-toolbar__plus{
|
.ce-toolbar__plus{
|
||||||
|
position: absolute;
|
||||||
background-image: url('fonts/codex_editor/icon-plus.svg');
|
background-image: url('fonts/codex_editor/icon-plus.svg');
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|
155
codex-editor.js
155
codex-editor.js
|
@ -60,23 +60,28 @@ var codex =
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Codex Team
|
||||||
|
* @version 1.0.6
|
||||||
|
*/
|
||||||
|
|
||||||
var codex = function (codex) {
|
var codex = function (codex) {
|
||||||
|
|
||||||
var init = function init() {
|
var init = function init() {
|
||||||
|
|
||||||
__webpack_require__(2);
|
codex.core = __webpack_require__(2);
|
||||||
__webpack_require__(3);
|
codex.ui = __webpack_require__(3);
|
||||||
__webpack_require__(4);
|
codex.transport = __webpack_require__(4);
|
||||||
__webpack_require__(5);
|
codex.renderer = __webpack_require__(5);
|
||||||
__webpack_require__(6);
|
codex.saver = __webpack_require__(6);
|
||||||
__webpack_require__(7);
|
codex.content = __webpack_require__(7);
|
||||||
__webpack_require__(8);
|
codex.toolbar = __webpack_require__(8);
|
||||||
__webpack_require__(12);
|
codex.tools = __webpack_require__(12);
|
||||||
__webpack_require__(13);
|
codex.callback = __webpack_require__(13);
|
||||||
__webpack_require__(14);
|
codex.draw = __webpack_require__(14);
|
||||||
__webpack_require__(15);
|
codex.caret = __webpack_require__(15);
|
||||||
__webpack_require__(16);
|
codex.notifications = __webpack_require__(16);
|
||||||
__webpack_require__(17);
|
codex.parser = __webpack_require__(17);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,14 +185,12 @@ var codex =
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 2 */
|
/* 2 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var core = function (core) {
|
var core = function (core) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -353,18 +356,14 @@ var codex =
|
||||||
return core;
|
return core;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.core = core;
|
|
||||||
|
|
||||||
module.exports = core;
|
module.exports = core;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 3 */
|
/* 3 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var ui = function (ui) {
|
var ui = function (ui) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -521,7 +520,7 @@ var codex =
|
||||||
|
|
||||||
tool = codex.tools[name];
|
tool = codex.tools[name];
|
||||||
|
|
||||||
if (tool.displayInToolbox == false) {
|
if (!tool.displayInToolbox) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,16 +717,21 @@ var codex =
|
||||||
return ui;
|
return ui;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.ui = ui;
|
module.exports = ui;
|
||||||
module.exports = codex;
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 4 */
|
/* 4 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
/**
|
||||||
|
*
|
||||||
|
* Codex.Editor Transport Module
|
||||||
|
*
|
||||||
|
* @author Codex Team
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
var transport = function (transport) {
|
var transport = function (transport) {
|
||||||
|
|
||||||
|
@ -822,17 +826,14 @@ var codex =
|
||||||
return transport;
|
return transport;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.transport = transport;
|
|
||||||
module.exports = transport;
|
module.exports = transport;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 5 */
|
/* 5 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var renderer = function (renderer) {
|
var renderer = function (renderer) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -954,7 +955,8 @@ var codex =
|
||||||
renderer.createBlockFromData = function (blockData) {
|
renderer.createBlockFromData = function (blockData) {
|
||||||
|
|
||||||
/** New parser */
|
/** New parser */
|
||||||
var pluginName = blockData.type;
|
var pluginName = blockData.type,
|
||||||
|
cover = blockData.cover;
|
||||||
|
|
||||||
/** Get first key of object that stores plugin name */
|
/** Get first key of object that stores plugin name */
|
||||||
// for (var pluginName in blockData) break;
|
// for (var pluginName in blockData) break;
|
||||||
|
@ -973,9 +975,6 @@ var codex =
|
||||||
/** New Parser */
|
/** New Parser */
|
||||||
var block = codex.tools[pluginName].render(blockData.data);
|
var block = codex.tools[pluginName].render(blockData.data);
|
||||||
|
|
||||||
/** Fire the render method with data */
|
|
||||||
// var block = codex.tools[pluginName].render(blockData[pluginName]);
|
|
||||||
|
|
||||||
/** is first-level block stretched */
|
/** is first-level block stretched */
|
||||||
var stretched = codex.tools[pluginName].isStretched || false;
|
var stretched = codex.tools[pluginName].isStretched || false;
|
||||||
|
|
||||||
|
@ -983,24 +982,22 @@ var codex =
|
||||||
return {
|
return {
|
||||||
type: pluginName,
|
type: pluginName,
|
||||||
block: block,
|
block: block,
|
||||||
stretched: stretched
|
stretched: stretched,
|
||||||
|
cover: cover
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.renderer = renderer;
|
|
||||||
module.exports = renderer;
|
module.exports = renderer;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 6 */
|
/* 6 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var saver = function (saver) {
|
var saver = function (saver) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1092,17 +1089,14 @@ var codex =
|
||||||
return saver;
|
return saver;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.saver = saver;
|
|
||||||
module.exports = saver;
|
module.exports = saver;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 7 */
|
/* 7 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var content = function (content) {
|
var content = function (content) {
|
||||||
|
|
||||||
content.currentNode = null;
|
content.currentNode = null;
|
||||||
|
@ -1275,10 +1269,15 @@ var codex =
|
||||||
var workingBlock = codex.content.currentNode,
|
var workingBlock = codex.content.currentNode,
|
||||||
newBlockContent = blockData.block,
|
newBlockContent = blockData.block,
|
||||||
blockType = blockData.type,
|
blockType = blockData.type,
|
||||||
|
cover = blockData.cover,
|
||||||
isStretched = blockData.stretched;
|
isStretched = blockData.stretched;
|
||||||
|
|
||||||
var newBlock = codex.content.composeNewBlock(newBlockContent, blockType, isStretched);
|
var newBlock = codex.content.composeNewBlock(newBlockContent, blockType, isStretched);
|
||||||
|
|
||||||
|
if (cover === true) {
|
||||||
|
newBlock.classList.add(codex.ui.className.BLOCK_IN_FEED_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
if (workingBlock) {
|
if (workingBlock) {
|
||||||
|
|
||||||
codex.core.insertAfter(workingBlock, newBlock);
|
codex.core.insertAfter(workingBlock, newBlock);
|
||||||
|
@ -1696,7 +1695,6 @@ var codex =
|
||||||
return content;
|
return content;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.content = content;
|
|
||||||
module.exports = content;
|
module.exports = content;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
|
@ -1705,8 +1703,6 @@ var codex =
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var toolbar = function (toolbar) {
|
var toolbar = function (toolbar) {
|
||||||
|
|
||||||
toolbar.init = function () {
|
toolbar.init = function () {
|
||||||
|
@ -1741,9 +1737,9 @@ var codex =
|
||||||
toolbar.close = function () {
|
toolbar.close = function () {
|
||||||
|
|
||||||
codex.nodes.toolbar.classList.remove('opened');
|
codex.nodes.toolbar.classList.remove('opened');
|
||||||
this.opened = false;
|
|
||||||
|
|
||||||
this.current = null;
|
toolbar.opened = false;
|
||||||
|
toolbar.current = null;
|
||||||
|
|
||||||
for (var button in codex.nodes.toolbarButtons) {
|
for (var button in codex.nodes.toolbarButtons) {
|
||||||
codex.nodes.toolbarButtons[button].classList.remove('selected');
|
codex.nodes.toolbarButtons[button].classList.remove('selected');
|
||||||
|
@ -1799,7 +1795,6 @@ var codex =
|
||||||
|
|
||||||
toolbar.init();
|
toolbar.init();
|
||||||
|
|
||||||
codex.toolbar = toolbar;
|
|
||||||
module.exports = toolbar;
|
module.exports = toolbar;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
|
@ -1808,8 +1803,6 @@ var codex =
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var settings = function (settings) {
|
var settings = function (settings) {
|
||||||
|
|
||||||
settings.init = function () {
|
settings.init = function () {
|
||||||
|
@ -2047,12 +2040,10 @@ var codex =
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 10 */
|
/* 10 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var inline = function (inline) {
|
var inline = function (inline) {
|
||||||
|
|
||||||
inline.init = function () {};
|
inline.init = function () {};
|
||||||
|
@ -2537,8 +2528,6 @@ var codex =
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var toolbox = function (toolbox) {
|
var toolbox = function (toolbox) {
|
||||||
|
|
||||||
toolbox.init = function () {
|
toolbox.init = function () {
|
||||||
|
@ -2581,7 +2570,6 @@ var codex =
|
||||||
toolbox.leaf = function () {
|
toolbox.leaf = function () {
|
||||||
|
|
||||||
var currentTool = codex.toolbar.current,
|
var currentTool = codex.toolbar.current,
|
||||||
tool,
|
|
||||||
tools = Object.keys(codex.tools),
|
tools = Object.keys(codex.tools),
|
||||||
barButtons = codex.nodes.toolbarButtons,
|
barButtons = codex.nodes.toolbarButtons,
|
||||||
nextToolIndex,
|
nextToolIndex,
|
||||||
|
@ -2589,7 +2577,7 @@ var codex =
|
||||||
toolToSelect;
|
toolToSelect;
|
||||||
|
|
||||||
/** Count toolbox hidden tools */
|
/** Count toolbox hidden tools */
|
||||||
for (tool in codex.tools) {
|
for (var tool in codex.tools) {
|
||||||
if (!codex.tools[tool].displayInToolbox) hiddenToolsAmount++;
|
if (!codex.tools[tool].displayInToolbox) hiddenToolsAmount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2603,20 +2591,20 @@ var codex =
|
||||||
|
|
||||||
nextToolIndex = tools.indexOf(currentTool) + 1;
|
nextToolIndex = tools.indexOf(currentTool) + 1;
|
||||||
|
|
||||||
var toolIsLastInToolbox = nextToolIndex == tools.length - (hiddenToolsAmount - 1);
|
var toolIsLastInToolbox = nextToolIndex == tools.length - (hiddenToolsAmount - 2);
|
||||||
|
|
||||||
if (toolIsLastInToolbox) {
|
if (toolIsLastInToolbox) {
|
||||||
|
|
||||||
nextToolIndex = 0;
|
nextToolIndex = 0;
|
||||||
|
|
||||||
/** getting first displayed tool */
|
/** getting first displayed tool */
|
||||||
for (tool in codex.tools) {
|
for (var tool in codex.tools) {
|
||||||
|
|
||||||
nextToolIndex++;
|
if (codex.tools[tool].displayInToolbox) {
|
||||||
|
|
||||||
if (!codex.tools[tool].displayInToolbox) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextToolIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2701,28 +2689,23 @@ var codex =
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 12 */
|
/* 12 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var tools = function (tools) {
|
var tools = function (tools) {
|
||||||
|
|
||||||
return tools;
|
return tools;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.tools = tools;
|
|
||||||
module.exports = tools;
|
module.exports = tools;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 13 */
|
/* 13 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var callbacks = function (callbacks) {
|
var callbacks = function (callbacks) {
|
||||||
|
|
||||||
callbacks.redactorSyncTimeout = null;
|
callbacks.redactorSyncTimeout = null;
|
||||||
|
@ -3305,7 +3288,7 @@ var codex =
|
||||||
range = codex.content.getRange();
|
range = codex.content.getRange();
|
||||||
selectionLength = range.endOffset - range.startOffset;
|
selectionLength = range.endOffset - range.startOffset;
|
||||||
|
|
||||||
if (codex.caret.position.atStart() && !selectionLength) {
|
if (codex.caret.position.atStart() && !selectionLength && codex.state.inputs[currentInputIndex - 1]) {
|
||||||
|
|
||||||
codex.content.mergeBlocks(currentInputIndex);
|
codex.content.mergeBlocks(currentInputIndex);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3424,17 +3407,14 @@ var codex =
|
||||||
return callbacks;
|
return callbacks;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.callback = callbacks;
|
|
||||||
module.exports = callbacks;
|
module.exports = callbacks;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 14 */
|
/* 14 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var draw = function (draw) {
|
var draw = function (draw) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3725,18 +3705,14 @@ var codex =
|
||||||
return draw;
|
return draw;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.draw = draw;
|
|
||||||
|
|
||||||
module.exports = draw;
|
module.exports = draw;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 15 */
|
/* 15 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var caret = function (caret) {
|
var caret = function (caret) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3966,17 +3942,14 @@ var codex =
|
||||||
return caret;
|
return caret;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.caret = caret;
|
|
||||||
module.exports = caret;
|
module.exports = caret;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 16 */
|
/* 16 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var notifications = function (notifications) {
|
var notifications = function (notifications) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3986,7 +3959,7 @@ var codex =
|
||||||
notifications.errorThrown = function (errorMsg, event) {
|
notifications.errorThrown = function (errorMsg, event) {
|
||||||
|
|
||||||
codex.notifications.send('This action is not available currently', event.type, false);
|
codex.notifications.send('This action is not available currently', event.type, false);
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends notification with different types
|
* Appends notification with different types
|
||||||
|
@ -4015,21 +3988,16 @@ var codex =
|
||||||
return notifications;
|
return notifications;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
codex.notifications = notifications;
|
|
||||||
module.exports = notifications;
|
module.exports = notifications;
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 17 */
|
/* 17 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var codex = __webpack_require__(1);
|
|
||||||
|
|
||||||
var parser = function (parser) {
|
var parser = function (parser) {
|
||||||
|
|
||||||
parser.init = function () {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits content by `\n` and returns blocks
|
* Splits content by `\n` and returns blocks
|
||||||
*/
|
*/
|
||||||
|
@ -4264,9 +4232,6 @@ var codex =
|
||||||
return parser;
|
return parser;
|
||||||
}({});
|
}({});
|
||||||
|
|
||||||
parser.init();
|
|
||||||
|
|
||||||
codex.parser = parser;
|
|
||||||
module.exports = parser;
|
module.exports = parser;
|
||||||
|
|
||||||
/***/ }
|
/***/ }
|
||||||
|
|
File diff suppressed because one or more lines are too long
31
editor.js
31
editor.js
|
@ -1,20 +1,25 @@
|
||||||
|
/**
|
||||||
|
* @author Codex Team
|
||||||
|
* @version 1.0.6
|
||||||
|
*/
|
||||||
|
|
||||||
var codex = (function(codex){
|
var codex = (function(codex){
|
||||||
|
|
||||||
var init = function() {
|
var init = function() {
|
||||||
|
|
||||||
require('./modules/core');
|
codex.core = require('./modules/core');
|
||||||
require('./modules/ui');
|
codex.ui = require('./modules/ui');
|
||||||
require('./modules/transport');
|
codex.transport = require('./modules/transport');
|
||||||
require('./modules/renderer');
|
codex.renderer = require('./modules/renderer');
|
||||||
require('./modules/saver');
|
codex.saver = require('./modules/saver');
|
||||||
require('./modules/content');
|
codex.content = require('./modules/content');
|
||||||
require('./modules/toolbar/toolbar');
|
codex.toolbar = require('./modules/toolbar/toolbar');
|
||||||
require('./modules/tools');
|
codex.tools = require('./modules/tools');
|
||||||
require('./modules/callbacks');
|
codex.callback = require('./modules/callbacks');
|
||||||
require('./modules/draw');
|
codex.draw = require('./modules/draw');
|
||||||
require('./modules/caret');
|
codex.caret = require('./modules/caret');
|
||||||
require('./modules/notifications');
|
codex.notifications = require('./modules/notifications');
|
||||||
require('./modules/parser');
|
codex.parser = require('./modules/parser');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
155
example.html
155
example.html
|
@ -10,12 +10,162 @@
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script src="./codex-editor.js?v=10"></script>
|
<script src="./codex-editor.js?v=11"></script>
|
||||||
<link rel="stylesheet" href="./codex-editor.css?v=10">
|
<link rel="stylesheet" href="./codex-editor.css?v=11">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="codex-editor.css">
|
||||||
|
|
||||||
|
<script src="plugins/paragraph/paragraph.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/paragraph/paragraph.css">
|
||||||
|
|
||||||
|
<script src="plugins/header/header.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/header/header.css">
|
||||||
|
|
||||||
|
<script src="plugins/code/code.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/code/code.css">
|
||||||
|
|
||||||
|
<script src="plugins/link/link.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/link/link.css">
|
||||||
|
|
||||||
|
<script src="plugins/quote/quote.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/quote/quote.css">
|
||||||
|
|
||||||
|
<script src="plugins/list/list.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/list/list.css">
|
||||||
|
|
||||||
|
<script src="plugins/image/image.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/image/image.css">
|
||||||
|
|
||||||
|
<script src="plugins/instagram/instagram.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/instagram/instagram.css">
|
||||||
|
|
||||||
|
<script src="plugins/twitter/twitter.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/twitter/twitter.css">
|
||||||
|
|
||||||
|
<script src="plugins/paste/paste.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/paste/paste.css">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
codex.start({
|
codex.start({
|
||||||
textareaId : "codex_area",
|
textareaId : "codex_area",
|
||||||
|
tools : {
|
||||||
|
paragraph: {
|
||||||
|
type: 'paragraph',
|
||||||
|
iconClassname: 'ce-icon-paragraph',
|
||||||
|
make: paragraphTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: null,
|
||||||
|
render: paragraphTool.render,
|
||||||
|
save: paragraphTool.save,
|
||||||
|
enableLineBreaks: false,
|
||||||
|
allowedToPaste: true
|
||||||
|
},
|
||||||
|
paste: {
|
||||||
|
type: 'paste',
|
||||||
|
iconClassname: '',
|
||||||
|
prepare: pasteTool.prepare,
|
||||||
|
make: pasteTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: null,
|
||||||
|
render: null,
|
||||||
|
save: pasteTool.save,
|
||||||
|
enableLineBreaks: false,
|
||||||
|
callbacks: pasteTool.callbacks,
|
||||||
|
allowedToPaste: false
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
type: 'header',
|
||||||
|
iconClassname: 'ce-icon-header',
|
||||||
|
make: headerTool.make,
|
||||||
|
appendCallback: headerTool.appendCallback,
|
||||||
|
settings: headerTool.makeSettings(),
|
||||||
|
render: headerTool.render,
|
||||||
|
save: headerTool.save,
|
||||||
|
displayInToolbox: true
|
||||||
|
},
|
||||||
|
code: {
|
||||||
|
type: 'code',
|
||||||
|
iconClassname: 'ce-icon-code',
|
||||||
|
make: codeTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: null,
|
||||||
|
render: codeTool.render,
|
||||||
|
save: codeTool.save,
|
||||||
|
displayInToolbox: true,
|
||||||
|
enableLineBreaks: true
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: 'link',
|
||||||
|
iconClassname: 'ce-icon-link',
|
||||||
|
make: linkTool.makeNewBlock,
|
||||||
|
appendCallback: linkTool.appendCallback,
|
||||||
|
render: linkTool.render,
|
||||||
|
save: linkTool.save,
|
||||||
|
displayInToolbox: true,
|
||||||
|
enableLineBreaks: true
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: 'list',
|
||||||
|
iconClassname: 'ce-icon-list-bullet',
|
||||||
|
make: listTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: listTool.makeSettings(),
|
||||||
|
render: listTool.render,
|
||||||
|
save: listTool.save,
|
||||||
|
displayInToolbox: true,
|
||||||
|
enableLineBreaks: true
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'quote',
|
||||||
|
iconClassname: 'ce-icon-quote',
|
||||||
|
make: quoteTools.makeBlockToAppend,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: quoteTools.makeSettings(),
|
||||||
|
render: quoteTools.render,
|
||||||
|
save: quoteTools.save,
|
||||||
|
displayInToolbox: true,
|
||||||
|
enableLineBreaks: true,
|
||||||
|
allowedToPaste: true
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
type: 'image',
|
||||||
|
iconClassname: 'ce-icon-picture',
|
||||||
|
make: ceImage.make,
|
||||||
|
appendCallback: ceImage.appendCallback,
|
||||||
|
settings: ceImage.makeSettings(),
|
||||||
|
render: ceImage.render,
|
||||||
|
save: ceImage.save,
|
||||||
|
isStretched: true,
|
||||||
|
displayInToolbox: true,
|
||||||
|
enableLineBreaks: false
|
||||||
|
},
|
||||||
|
instagram: {
|
||||||
|
type: 'instagram',
|
||||||
|
iconClassname: 'ce-icon-instagram',
|
||||||
|
prepare: instagramTool.prepare,
|
||||||
|
make: instagramTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: null,
|
||||||
|
render: instagramTool.reneder,
|
||||||
|
save: instagramTool.save,
|
||||||
|
displayInToolbox: false,
|
||||||
|
enableLineBreaks: false,
|
||||||
|
allowedToPaste: false
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
type: 'twitter',
|
||||||
|
iconClassname: 'ce-icon-twitter',
|
||||||
|
prepare: twitterTool.prepare,
|
||||||
|
make: twitterTool.make,
|
||||||
|
appendCallback: null,
|
||||||
|
settings: null,
|
||||||
|
render: twitterTool.render,
|
||||||
|
save: twitterTool.save,
|
||||||
|
displayInToolbox: false,
|
||||||
|
enableLineBreaks: false,
|
||||||
|
allowedToPaste: false
|
||||||
|
}
|
||||||
|
},
|
||||||
data : {
|
data : {
|
||||||
items: [],
|
items: [],
|
||||||
count: 0
|
count: 0
|
||||||
|
@ -23,5 +173,4 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="codex-editor.css">
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var callbacks = (function(callbacks) {
|
var callbacks = (function(callbacks) {
|
||||||
|
|
||||||
callbacks.redactorSyncTimeout = null;
|
callbacks.redactorSyncTimeout = null;
|
||||||
|
@ -623,7 +621,8 @@ var callbacks = (function(callbacks) {
|
||||||
range = codex.content.getRange();
|
range = codex.content.getRange();
|
||||||
selectionLength = range.endOffset - range.startOffset;
|
selectionLength = range.endOffset - range.startOffset;
|
||||||
|
|
||||||
if (codex.caret.position.atStart() && !selectionLength) {
|
|
||||||
|
if (codex.caret.position.atStart() && !selectionLength && codex.state.inputs[currentInputIndex - 1]) {
|
||||||
|
|
||||||
codex.content.mergeBlocks(currentInputIndex);
|
codex.content.mergeBlocks(currentInputIndex);
|
||||||
|
|
||||||
|
@ -754,5 +753,4 @@ var callbacks = (function(callbacks) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.callback = callbacks;
|
|
||||||
module.exports = callbacks;
|
module.exports = callbacks;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var caret = (function(caret) {
|
var caret = (function(caret) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,5 +235,4 @@ var caret = (function(caret) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.caret = caret;
|
|
||||||
module.exports = caret;
|
module.exports = caret;
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var content = (function(content) {
|
var content = (function(content) {
|
||||||
|
|
||||||
content.currentNode = null;
|
content.currentNode = null;
|
||||||
|
@ -179,10 +177,15 @@ var content = (function(content) {
|
||||||
var workingBlock = codex.content.currentNode,
|
var workingBlock = codex.content.currentNode,
|
||||||
newBlockContent = blockData.block,
|
newBlockContent = blockData.block,
|
||||||
blockType = blockData.type,
|
blockType = blockData.type,
|
||||||
|
cover = blockData.cover,
|
||||||
isStretched = blockData.stretched;
|
isStretched = blockData.stretched;
|
||||||
|
|
||||||
var newBlock = codex.content.composeNewBlock(newBlockContent, blockType, isStretched);
|
var newBlock = codex.content.composeNewBlock(newBlockContent, blockType, isStretched);
|
||||||
|
|
||||||
|
if (cover === true) {
|
||||||
|
newBlock.classList.add(codex.ui.className.BLOCK_IN_FEED_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
if (workingBlock) {
|
if (workingBlock) {
|
||||||
|
|
||||||
codex.core.insertAfter(workingBlock, newBlock);
|
codex.core.insertAfter(workingBlock, newBlock);
|
||||||
|
@ -461,7 +464,7 @@ var content = (function(content) {
|
||||||
codex.content.insertBlock({
|
codex.content.insertBlock({
|
||||||
type : NEW_BLOCK_TYPE,
|
type : NEW_BLOCK_TYPE,
|
||||||
block : codex.tools[NEW_BLOCK_TYPE].render({
|
block : codex.tools[NEW_BLOCK_TYPE].render({
|
||||||
text : newNode,
|
text : newNode
|
||||||
})
|
})
|
||||||
}, true );
|
}, true );
|
||||||
|
|
||||||
|
@ -627,5 +630,4 @@ var content = (function(content) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.content = content;
|
|
||||||
module.exports = content;
|
module.exports = content;
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('./../editor');
|
|
||||||
|
|
||||||
var core = (function(core) {
|
var core = (function(core) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,8 +172,6 @@ var core = (function(core) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.core = core;
|
|
||||||
|
|
||||||
module.exports = core;
|
module.exports = core;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var draw = (function(draw) {
|
var draw = (function(draw) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,8 +302,6 @@ var draw = (function(draw) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.draw = draw;
|
|
||||||
|
|
||||||
module.exports = draw;
|
module.exports = draw;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var notifications = (function(notifications) {
|
var notifications = (function(notifications) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +8,7 @@ var notifications = (function(notifications) {
|
||||||
|
|
||||||
codex.notifications.send('This action is not available currently', event.type, false);
|
codex.notifications.send('This action is not available currently', event.type, false);
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends notification with different types
|
* Appends notification with different types
|
||||||
|
@ -41,5 +39,4 @@ var notifications = (function(notifications) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.notifications = notifications;
|
|
||||||
module.exports = notifications;
|
module.exports = notifications;
|
|
@ -1,11 +1,5 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var parser = (function(parser) {
|
var parser = (function(parser) {
|
||||||
|
|
||||||
parser.init = function() {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits content by `\n` and returns blocks
|
* Splits content by `\n` and returns blocks
|
||||||
*/
|
*/
|
||||||
|
@ -255,7 +249,4 @@ var parser = (function(parser) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
parser.init();
|
|
||||||
|
|
||||||
codex.parser = parser;
|
|
||||||
module.exports = parser;
|
module.exports = parser;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var renderer = (function(renderer) {
|
var renderer = (function(renderer) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,7 +127,8 @@ var renderer = (function(renderer) {
|
||||||
renderer.createBlockFromData = function (blockData) {
|
renderer.createBlockFromData = function (blockData) {
|
||||||
|
|
||||||
/** New parser */
|
/** New parser */
|
||||||
var pluginName = blockData.type;
|
var pluginName = blockData.type,
|
||||||
|
cover = blockData.cover;
|
||||||
|
|
||||||
/** Get first key of object that stores plugin name */
|
/** Get first key of object that stores plugin name */
|
||||||
// for (var pluginName in blockData) break;
|
// for (var pluginName in blockData) break;
|
||||||
|
@ -148,9 +147,6 @@ var renderer = (function(renderer) {
|
||||||
/** New Parser */
|
/** New Parser */
|
||||||
var block = codex.tools[pluginName].render(blockData.data);
|
var block = codex.tools[pluginName].render(blockData.data);
|
||||||
|
|
||||||
/** Fire the render method with data */
|
|
||||||
// var block = codex.tools[pluginName].render(blockData[pluginName]);
|
|
||||||
|
|
||||||
/** is first-level block stretched */
|
/** is first-level block stretched */
|
||||||
var stretched = codex.tools[pluginName].isStretched || false;
|
var stretched = codex.tools[pluginName].isStretched || false;
|
||||||
|
|
||||||
|
@ -158,7 +154,8 @@ var renderer = (function(renderer) {
|
||||||
return {
|
return {
|
||||||
type : pluginName,
|
type : pluginName,
|
||||||
block : block,
|
block : block,
|
||||||
stretched : stretched
|
stretched : stretched,
|
||||||
|
cover : cover
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -167,5 +164,4 @@ var renderer = (function(renderer) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.renderer = renderer;
|
|
||||||
module.exports = renderer;
|
module.exports = renderer;
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var saver = (function(saver) {
|
var saver = (function(saver) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,5 +105,4 @@ var saver = (function(saver) {
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.saver = saver;
|
|
||||||
module.exports = saver;
|
module.exports = saver;
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../../editor');
|
|
||||||
|
|
||||||
var inline = (function(inline) {
|
var inline = (function(inline) {
|
||||||
|
|
||||||
inline.init = function() {
|
inline.init = function() {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../../editor');
|
|
||||||
|
|
||||||
var settings = (function(settings) {
|
var settings = (function(settings) {
|
||||||
|
|
||||||
settings.init = function() {
|
settings.init = function() {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../../editor');
|
|
||||||
|
|
||||||
var toolbar = (function(toolbar) {
|
var toolbar = (function(toolbar) {
|
||||||
|
|
||||||
toolbar.init = function() {
|
toolbar.init = function() {
|
||||||
|
@ -35,9 +33,9 @@ var toolbar = (function(toolbar) {
|
||||||
toolbar.close = function(){
|
toolbar.close = function(){
|
||||||
|
|
||||||
codex.nodes.toolbar.classList.remove('opened');
|
codex.nodes.toolbar.classList.remove('opened');
|
||||||
this.opened = false;
|
|
||||||
|
|
||||||
this.current = null;
|
toolbar.opened = false;
|
||||||
|
toolbar.current = null;
|
||||||
|
|
||||||
for (var button in codex.nodes.toolbarButtons){
|
for (var button in codex.nodes.toolbarButtons){
|
||||||
codex.nodes.toolbarButtons[button].classList.remove('selected');
|
codex.nodes.toolbarButtons[button].classList.remove('selected');
|
||||||
|
@ -99,6 +97,5 @@ var toolbar = (function(toolbar) {
|
||||||
|
|
||||||
toolbar.init();
|
toolbar.init();
|
||||||
|
|
||||||
codex.toolbar = toolbar;
|
|
||||||
module.exports = toolbar;
|
module.exports = toolbar;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../../editor');
|
|
||||||
|
|
||||||
var toolbox = (function(toolbox) {
|
var toolbox = (function(toolbox) {
|
||||||
|
|
||||||
toolbox.init = function() {
|
toolbox.init = function() {
|
||||||
|
@ -44,7 +42,6 @@ var toolbox = (function(toolbox) {
|
||||||
toolbox.leaf = function(){
|
toolbox.leaf = function(){
|
||||||
|
|
||||||
var currentTool = codex.toolbar.current,
|
var currentTool = codex.toolbar.current,
|
||||||
tool,
|
|
||||||
tools = Object.keys(codex.tools),
|
tools = Object.keys(codex.tools),
|
||||||
barButtons = codex.nodes.toolbarButtons,
|
barButtons = codex.nodes.toolbarButtons,
|
||||||
nextToolIndex,
|
nextToolIndex,
|
||||||
|
@ -52,7 +49,7 @@ var toolbox = (function(toolbox) {
|
||||||
toolToSelect;
|
toolToSelect;
|
||||||
|
|
||||||
/** Count toolbox hidden tools */
|
/** Count toolbox hidden tools */
|
||||||
for( tool in codex.tools ) {
|
for( var tool in codex.tools ) {
|
||||||
if (!codex.tools[tool].displayInToolbox)
|
if (!codex.tools[tool].displayInToolbox)
|
||||||
hiddenToolsAmount ++;
|
hiddenToolsAmount ++;
|
||||||
}
|
}
|
||||||
|
@ -66,20 +63,20 @@ var toolbox = (function(toolbox) {
|
||||||
|
|
||||||
nextToolIndex = tools.indexOf(currentTool) + 1;
|
nextToolIndex = tools.indexOf(currentTool) + 1;
|
||||||
|
|
||||||
var toolIsLastInToolbox = nextToolIndex == tools.length - (hiddenToolsAmount - 1);
|
var toolIsLastInToolbox = nextToolIndex == tools.length - (hiddenToolsAmount - 2);
|
||||||
|
|
||||||
if ( toolIsLastInToolbox ) {
|
if ( toolIsLastInToolbox ) {
|
||||||
|
|
||||||
nextToolIndex = 0;
|
nextToolIndex = 0;
|
||||||
|
|
||||||
/** getting first displayed tool */
|
/** getting first displayed tool */
|
||||||
for( tool in codex.tools ) {
|
for( var tool in codex.tools ) {
|
||||||
|
|
||||||
nextToolIndex ++;
|
if (codex.tools[tool].displayInToolbox){
|
||||||
|
|
||||||
if (!codex.tools[tool].displayInToolbox){
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextToolIndex ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var tools = (function(tools) {
|
var tools = (function(tools) {
|
||||||
|
|
||||||
return tools;
|
return tools;
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.tools = tools;
|
|
||||||
module.exports = tools;
|
module.exports = tools;
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
var codex = require('../editor');
|
/**
|
||||||
|
*
|
||||||
|
* Codex.Editor Transport Module
|
||||||
|
*
|
||||||
|
* @author Codex Team
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
var transport = (function(transport){
|
var transport = (function(transport){
|
||||||
|
|
||||||
|
@ -97,5 +103,4 @@ var transport = (function(transport){
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.transport = transport;
|
|
||||||
module.exports = transport;
|
module.exports = transport;
|
|
@ -1,5 +1,3 @@
|
||||||
var codex = require('../editor');
|
|
||||||
|
|
||||||
var ui = (function(ui){
|
var ui = (function(ui){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,7 +167,7 @@ var ui = (function(ui){
|
||||||
|
|
||||||
tool = codex.tools[name];
|
tool = codex.tools[name];
|
||||||
|
|
||||||
if (tool.displayInToolbox == false) {
|
if (!tool.displayInToolbox) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,5 +377,4 @@ var ui = (function(ui){
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
codex.ui = ui;
|
module.exports = ui;
|
||||||
module.exports = codex;
|
|
|
@ -8,7 +8,9 @@
|
||||||
},
|
},
|
||||||
"author": "Codex Team",
|
"author": "Codex Team",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"whatwg-fetch": "^2.0.1"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.21.0",
|
"babel-core": "^6.21.0",
|
||||||
"babel-loader": "^6.2.10",
|
"babel-loader": "^6.2.10",
|
||||||
|
|
25
plugins/code/code.css
Normal file
25
plugins/code/code.css
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
.ce-code {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid #ebeef3;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #fdfdff !important;
|
||||||
|
|
||||||
|
margin: 1em 0 !important;
|
||||||
|
padding: .5em .8em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
|
||||||
|
font-family: 'monospace', 'monaco', 'consolas', 'courier';
|
||||||
|
line-height: 1.5em;
|
||||||
|
color: #325179;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CodeX Editor styles overlay
|
||||||
|
* @todo change for ce-tool-wrapper__code
|
||||||
|
*/
|
||||||
|
.ce_block[data-type="code"]{
|
||||||
|
padding: 1em 0 !important;
|
||||||
|
}
|
54
plugins/code/code.js
Normal file
54
plugins/code/code.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* Code Plugin\
|
||||||
|
* Creates code tag and adds content to this tag
|
||||||
|
*/
|
||||||
|
var codeTool = {
|
||||||
|
|
||||||
|
baseClass : "ce-code",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make initial header block
|
||||||
|
* @param {object} JSON with block data
|
||||||
|
* @return {Element} element to append
|
||||||
|
*/
|
||||||
|
make : function (data) {
|
||||||
|
|
||||||
|
var tag = document.createElement('code');
|
||||||
|
|
||||||
|
tag.classList.add(codeTool.baseClass);
|
||||||
|
|
||||||
|
if (data && data.text) {
|
||||||
|
tag.innerHTML = data.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.contentEditable = true;
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render HTML block from JSON
|
||||||
|
*/
|
||||||
|
render : function (data) {
|
||||||
|
|
||||||
|
return codeTool.make(data);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to extract JSON data from HTML block
|
||||||
|
*/
|
||||||
|
save : function (blockContent){
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
text : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
data.text = blockContent.innerHTML;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
41
plugins/header/header.css
Normal file
41
plugins/header/header.css
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* Plugin styles
|
||||||
|
*/
|
||||||
|
.ce-header {
|
||||||
|
padding: .7em 0;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
.ce-header p,
|
||||||
|
.ce-header div{
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** H e a d e r - settings */
|
||||||
|
.ce_plugin_header--select_button{
|
||||||
|
display: block;
|
||||||
|
color: #306ac7;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
.ce_plugin_header--select_button:not(:last-of-type){
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.ce_plugin_header--select_button:hover{
|
||||||
|
color: #a1b4ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty header placeholder
|
||||||
|
*/
|
||||||
|
.ce-header:empty::before{
|
||||||
|
content : attr(data-placeholder);
|
||||||
|
color: #818BA1;
|
||||||
|
opacity: .7;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
.ce-header:focus::before{
|
||||||
|
opacity: .1;
|
||||||
|
}
|
160
plugins/header/header.js
Normal file
160
plugins/header/header.js
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/**
|
||||||
|
* Example of making plugin
|
||||||
|
* H e a d e r
|
||||||
|
*/
|
||||||
|
var headerTool = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make initial header block
|
||||||
|
* @param {object} JSON with block data
|
||||||
|
* @return {Element} element to append
|
||||||
|
*/
|
||||||
|
make : function (data) {
|
||||||
|
|
||||||
|
var availableTypes = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
|
||||||
|
tag;
|
||||||
|
|
||||||
|
if (data && data.type && availableTypes.includes(data.type)) {
|
||||||
|
|
||||||
|
tag = document.createElement( data.type );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save header type in data-attr.
|
||||||
|
* We need it in save method to extract type from HTML to JSON
|
||||||
|
*/
|
||||||
|
tag.dataset.headerData = data.type;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tag = document.createElement( 'H2' );
|
||||||
|
tag.dataset.headerData = 'H2';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data && data.text) {
|
||||||
|
tag.textContent = data.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.classList.add('ce-header');
|
||||||
|
tag.setAttribute('data-placeholder', 'Heading');
|
||||||
|
tag.contentEditable = true;
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render HTML block from JSON
|
||||||
|
*/
|
||||||
|
render : function (data) {
|
||||||
|
|
||||||
|
return headerTool.make(data);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to extract JSON data from HTML block
|
||||||
|
*/
|
||||||
|
save : function (blockContent) {
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
"heading-styles": blockContent.dataset.headerData,
|
||||||
|
format:"html",
|
||||||
|
text : null,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
data.text = blockContent.textContent;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block appending callback
|
||||||
|
*/
|
||||||
|
appendCallback : function (argument) {
|
||||||
|
|
||||||
|
console.log('header appended...');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings panel content
|
||||||
|
* - - - - - - - - - - - - -
|
||||||
|
* | настройки H1 H2 H3 |
|
||||||
|
* - - - - - - - - - - - - -
|
||||||
|
* @return {Element} element contains all settings
|
||||||
|
*/
|
||||||
|
makeSettings : function () {
|
||||||
|
|
||||||
|
var holder = document.createElement('DIV'),
|
||||||
|
types = {
|
||||||
|
H2: 'Заголовок раздела',
|
||||||
|
H3: 'Подзаголовок',
|
||||||
|
H4: 'Заголовок 3-его уровня'
|
||||||
|
},
|
||||||
|
selectTypeButton;
|
||||||
|
|
||||||
|
/** Add holder classname */
|
||||||
|
holder.className = 'ce_plugin_header--settings';
|
||||||
|
|
||||||
|
/** Now add type selectors */
|
||||||
|
for (var type in types){
|
||||||
|
|
||||||
|
selectTypeButton = document.createElement('SPAN');
|
||||||
|
|
||||||
|
selectTypeButton.textContent = types[type];
|
||||||
|
selectTypeButton.className = 'ce_plugin_header--select_button';
|
||||||
|
|
||||||
|
this.addSelectTypeClickListener(selectTypeButton, type);
|
||||||
|
|
||||||
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds click event to passed button
|
||||||
|
*/
|
||||||
|
addSelectTypeClickListener : function (el, type) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function () {
|
||||||
|
|
||||||
|
headerTool.selectTypeClicked(type);
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces old header with new type
|
||||||
|
* @params {string} type - new header tagName: H1—H6
|
||||||
|
*/
|
||||||
|
selectTypeClicked : function (type) {
|
||||||
|
|
||||||
|
var old_header, new_header;
|
||||||
|
|
||||||
|
/** Now current header stored as a currentNode */
|
||||||
|
old_header = codex.content.currentNode.querySelector('[contentEditable]');
|
||||||
|
|
||||||
|
/** Making new header */
|
||||||
|
new_header = document.createElement(type);
|
||||||
|
|
||||||
|
new_header.innerHTML = old_header.innerHTML;
|
||||||
|
new_header.contentEditable = true;
|
||||||
|
new_header.setAttribute('data-placeholder', 'Heading');
|
||||||
|
new_header.classList.add('ce-header');
|
||||||
|
|
||||||
|
new_header.dataset.headerData = type;
|
||||||
|
|
||||||
|
codex.content.switchBlock(old_header, new_header, 'header');
|
||||||
|
|
||||||
|
/** Close settings after replacing */
|
||||||
|
codex.toolbar.settings.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
118
plugins/image/image.css
Normal file
118
plugins/image/image.css
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
* Image plugin for codex-editor
|
||||||
|
* @author CodeX Team <team@ifmo.su>
|
||||||
|
*
|
||||||
|
* @version 0.0.1
|
||||||
|
*/
|
||||||
|
.ce-image {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** upload image form */
|
||||||
|
.ce-plugin-image__holder{
|
||||||
|
position: relative;
|
||||||
|
background: #FEFEFE;
|
||||||
|
border: 2px solid #edeff5;
|
||||||
|
text-align: center;
|
||||||
|
margin: 30px 0;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__holder input{
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
outline: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for Chrome */
|
||||||
|
.ce-plugin-image__holder input::-webkit-input-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for IE 10+ */
|
||||||
|
.ce-plugin-image__holder input:-ms-input-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for Firefox 19+ */
|
||||||
|
.ce-plugin-image__holder input::-moz-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__loader {
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: repeating-linear-gradient(-45deg, transparent, transparent 4px, #f5f9ff 4px, #eaedef 8px) !important;
|
||||||
|
background-size: 56px 56px;
|
||||||
|
animation: loading-bar 5s infinite linear;
|
||||||
|
}
|
||||||
|
@keyframes loading-bar {
|
||||||
|
100% { background-position: -56% 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.ce-plugin-image__button{
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1;
|
||||||
|
color: #8990AA;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__button:hover{
|
||||||
|
color: #393F52;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Uploaded image */
|
||||||
|
.ce-plugin-image__wrapper {
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__uploaded--centered {
|
||||||
|
display: block;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__uploaded--stretched {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__firstlevel--stretch {
|
||||||
|
margin: 0 !important;
|
||||||
|
max-width: none !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: .5em auto 0;
|
||||||
|
padding: .5em;
|
||||||
|
text-align: center;
|
||||||
|
color: #898a8c;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ebeef3;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption:empty::before {
|
||||||
|
content: 'Введите подпись';
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #a1a5b3;;
|
||||||
|
opacity: .9;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption:focus::before {
|
||||||
|
opacity: .1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Settings */
|
||||||
|
.ce_plugin_image--select_button{
|
||||||
|
display: block;
|
||||||
|
color: #306ac7;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
.ce_plugin_image--select_button:not(:last-of-type){
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.ce_plugin_image--select_button:hover{
|
||||||
|
color: #a1b4ec;
|
||||||
|
}
|
402
plugins/image/image.js
Normal file
402
plugins/image/image.js
Normal file
|
@ -0,0 +1,402 @@
|
||||||
|
/**
|
||||||
|
* Image plugin for codex-editor
|
||||||
|
* @author CodeX Team <team@ifmo.su>
|
||||||
|
*
|
||||||
|
* @version 1.1.3
|
||||||
|
*/
|
||||||
|
var ceImage = {
|
||||||
|
|
||||||
|
elementClasses : {
|
||||||
|
|
||||||
|
ce_image : 'ce-image',
|
||||||
|
loading : 'ce-plugin-image__loader',
|
||||||
|
blockStretched: 'ce-block--stretched',
|
||||||
|
uploadedImage : {
|
||||||
|
centered : 'ce-plugin-image__uploaded--centered',
|
||||||
|
stretched : 'ce-plugin-image__uploaded--stretched',
|
||||||
|
},
|
||||||
|
imageCaption : 'ce-plugin-image__caption',
|
||||||
|
imageWrapper : 'ce-plugin-image__wrapper',
|
||||||
|
formHolder : 'ce-plugin-image__holder',
|
||||||
|
uploadButton : 'ce-plugin-image__button',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
holder : null,
|
||||||
|
|
||||||
|
/** Default path to redactors images */
|
||||||
|
path : '/upload/redactor_images/',
|
||||||
|
|
||||||
|
make : function ( data ) {
|
||||||
|
|
||||||
|
var holder;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
|
||||||
|
if ( data.isStretch !== 'true') {
|
||||||
|
holder = ceImage.ui.makeImage(data, ceImage.elementClasses.uploadedImage.centered, 'false');
|
||||||
|
} else {
|
||||||
|
holder = ceImage.ui.makeImage(data, ceImage.elementClasses.uploadedImage.stretched, 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
holder = ceImage.ui.makeForm();
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this tool works when tool is clicked in toolbox
|
||||||
|
*/
|
||||||
|
appendCallback : function(event) {
|
||||||
|
|
||||||
|
/** Upload image and call success callback*/
|
||||||
|
ceImage.uploadButtonClicked(event);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings panel content
|
||||||
|
* @return {Element} element contains all settings
|
||||||
|
*/
|
||||||
|
makeSettings : function () {
|
||||||
|
|
||||||
|
var holder = document.createElement('DIV'),
|
||||||
|
types = {
|
||||||
|
centered : 'По центру',
|
||||||
|
stretched : 'На всю ширину',
|
||||||
|
},
|
||||||
|
selectTypeButton;
|
||||||
|
|
||||||
|
/** Add holder classname */
|
||||||
|
holder.className = 'ce_plugin_image--settings';
|
||||||
|
|
||||||
|
/** Now add type selectors */
|
||||||
|
for (var type in types){
|
||||||
|
|
||||||
|
selectTypeButton = document.createElement('SPAN');
|
||||||
|
|
||||||
|
selectTypeButton.textContent = types[type];
|
||||||
|
selectTypeButton.className = 'ce_plugin_image--select_button';
|
||||||
|
|
||||||
|
this.addSelectTypeClickListener(selectTypeButton, type);
|
||||||
|
|
||||||
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addSelectTypeClickListener : function(el, type) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function() {
|
||||||
|
|
||||||
|
ceImage.selectTypeClicked(type);
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
selectTypeClicked : function(type) {
|
||||||
|
|
||||||
|
var current = codex.content.currentNode,
|
||||||
|
blockContent = current.childNodes[0],
|
||||||
|
image = ceImage.ui.getImage(current),
|
||||||
|
wrapper = current.querySelector('.' + ceImage.elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
/** Clear classList */
|
||||||
|
current.className = '';
|
||||||
|
image.className = '';
|
||||||
|
|
||||||
|
/** Add important first-level class ce_block */
|
||||||
|
current.classList.add(codex.ui.className.BLOCK_CLASSNAME);
|
||||||
|
|
||||||
|
if (type === 'stretched') {
|
||||||
|
|
||||||
|
image.classList.add(ceImage.elementClasses.uploadedImage.stretched);
|
||||||
|
|
||||||
|
blockContent.classList.add(ceImage.elementClasses.blockStretched);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = true;
|
||||||
|
|
||||||
|
} else if (type === 'centered') {
|
||||||
|
|
||||||
|
image.classList.add(ceImage.elementClasses.uploadedImage.centered);
|
||||||
|
|
||||||
|
blockContent.classList.remove(ceImage.elementClasses.blockStretched);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function( data ) {
|
||||||
|
|
||||||
|
return this.make(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
save : function ( block ) {
|
||||||
|
|
||||||
|
var content = block,
|
||||||
|
image = ceImage.ui.getImage(content),
|
||||||
|
caption = content.querySelector('.' + ceImage.elementClasses.imageCaption);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
background : false,
|
||||||
|
border : false,
|
||||||
|
isStretch : content.dataset.stretched,
|
||||||
|
file : {
|
||||||
|
url : image.src,
|
||||||
|
bigUrl : null,
|
||||||
|
width : image.width,
|
||||||
|
height : image.height,
|
||||||
|
additionalData :null,
|
||||||
|
},
|
||||||
|
caption : caption.textContent,
|
||||||
|
cover : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadButtonClicked : function(event) {
|
||||||
|
|
||||||
|
var beforeSend = ceImage.photoUploadingCallbacks.beforeSend,
|
||||||
|
success = ceImage.photoUploadingCallbacks.success,
|
||||||
|
error = ceImage.photoUploadingCallbacks.error;
|
||||||
|
|
||||||
|
/** Define callbacks */
|
||||||
|
codex.transport.selectAndUpload({
|
||||||
|
beforeSend,
|
||||||
|
success,
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ceImage.ui = {
|
||||||
|
|
||||||
|
holder : function(){
|
||||||
|
|
||||||
|
var element = document.createElement('DIV');
|
||||||
|
|
||||||
|
element.classList.add(ceImage.elementClasses.formHolder);
|
||||||
|
element.classList.add(ceImage.elementClasses.ce_image);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadButton : function(){
|
||||||
|
|
||||||
|
var button = document.createElement('SPAN');
|
||||||
|
|
||||||
|
button.classList.add(ceImage.elementClasses.uploadButton);
|
||||||
|
|
||||||
|
button.innerHTML = '<i class="ce-icon-picture"> </i>';
|
||||||
|
button.innerHTML += 'Загрузить фотографию';
|
||||||
|
|
||||||
|
return button;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} source - file path
|
||||||
|
* @param {string} style - css class
|
||||||
|
* @return {object} image - document IMG tag
|
||||||
|
*/
|
||||||
|
image : function(source, style) {
|
||||||
|
|
||||||
|
var image = document.createElement('IMG');
|
||||||
|
|
||||||
|
image.classList.add(style);
|
||||||
|
|
||||||
|
image.src = source;
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapper : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(ceImage.elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
|
||||||
|
caption : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(ceImage.elementClasses.imageCaption);
|
||||||
|
div.contentEditable = true;
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Draws form for image upload
|
||||||
|
*/
|
||||||
|
makeForm : function() {
|
||||||
|
|
||||||
|
var holder = ceImage.ui.holder(),
|
||||||
|
uploadButton = ceImage.ui.uploadButton();
|
||||||
|
|
||||||
|
holder.appendChild(uploadButton);
|
||||||
|
|
||||||
|
uploadButton.addEventListener('click', ceImage.uploadButtonClicked, false );
|
||||||
|
|
||||||
|
ceImage.holder = holder;
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @param {string} imageTypeClass - plugin's style
|
||||||
|
* @param {boolean} stretched - stretched or not
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
makeImage : function(data, imageTypeClass, stretched) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, imageTypeClass),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = stretched;
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTML} data - Rendered block with image
|
||||||
|
*/
|
||||||
|
getImage : function(data) {
|
||||||
|
|
||||||
|
var image = data.querySelector('.' + ceImage.elementClasses.uploadedImage.centered) ||
|
||||||
|
data.querySelector('.' + ceImage.elementClasses.uploadedImage.stretched);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
centeredImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.centered),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = 'false';
|
||||||
|
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return stretched image
|
||||||
|
*/
|
||||||
|
stretchedImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.stretched),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = 'true';
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ceImage.photoUploadingCallbacks = {
|
||||||
|
|
||||||
|
/** Before sending ajax request */
|
||||||
|
beforeSend : function() {
|
||||||
|
ceImage.holder.classList.add(ceImage.elementClasses.loading);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Photo was uploaded successfully */
|
||||||
|
success : function(result) {
|
||||||
|
|
||||||
|
var parsed = JSON.parse(result),
|
||||||
|
data,
|
||||||
|
currentBlock = codex.content.currentNode,
|
||||||
|
image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preparing {Object} data to draw an image
|
||||||
|
* @uses ceImage.make method
|
||||||
|
*/
|
||||||
|
data = {
|
||||||
|
background : false,
|
||||||
|
border : false,
|
||||||
|
isStretch : false,
|
||||||
|
file : {
|
||||||
|
url : ceImage.path + 'o_' + parsed.filename,
|
||||||
|
bigUrl : null,
|
||||||
|
width : null,
|
||||||
|
height : null,
|
||||||
|
additionalData : null,
|
||||||
|
},
|
||||||
|
caption : '',
|
||||||
|
cover : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
image = ceImage.make(data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If current block is empty, we can replace it to uploaded image
|
||||||
|
* Or insert new block
|
||||||
|
*/
|
||||||
|
codex.content.switchBlock(ceImage.holder, image, 'image');
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
|
||||||
|
error : function(result) {
|
||||||
|
console.log('Choosen file is not an image or image is corrupted');
|
||||||
|
codex.notifications.errorThrown();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
106
plugins/images/images.css
Normal file
106
plugins/images/images.css
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
* Image plugin for codex-editor
|
||||||
|
* @author CodeX Team <team@ifmo.su>
|
||||||
|
*
|
||||||
|
* @version 0.0.1
|
||||||
|
*/
|
||||||
|
.ce-image {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 20px auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__holder{
|
||||||
|
position: relative;
|
||||||
|
background: #FEFEFE;
|
||||||
|
border: 2px dashed #E8EBF5;
|
||||||
|
border-radius: 55px;
|
||||||
|
margin: 30px 0;
|
||||||
|
padding: 30px 110px 30px 40px;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__holder input{
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
outline: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for Chrome */
|
||||||
|
.ce-plugin-image__holder input::-webkit-input-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for IE 10+ */
|
||||||
|
.ce-plugin-image__holder input:-ms-input-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
}
|
||||||
|
/* Placeholder color for Firefox 19+ */
|
||||||
|
.ce-plugin-image__holder input::-moz-placeholder {
|
||||||
|
color: #A5ABBC;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__button{
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
right: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "codex_editor";
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #8990AA;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__button:hover{
|
||||||
|
color: #393F52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__wrapper {
|
||||||
|
margin : 3em 0;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__uploaded--centered {
|
||||||
|
max-width: 700px;
|
||||||
|
display:block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__uploaded--stretched {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ce-plugin-image__firstlevel--stretch {
|
||||||
|
margin: 0 !important;
|
||||||
|
max-width: none !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 1em auto;
|
||||||
|
text-align: center;
|
||||||
|
color: #898a8c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption:empty::before {
|
||||||
|
content: 'Введите подпись';
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #a1a5b3;;
|
||||||
|
opacity: .9;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-plugin-image__caption:focus::before {
|
||||||
|
opacity: .1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Settings */
|
||||||
|
.ce_plugin_image--settings{
|
||||||
|
white-space: nowrap;
|
||||||
|
/*padding-right: 10px; */
|
||||||
|
}
|
||||||
|
.ce_plugin_image--select_button{
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 15px;
|
||||||
|
color: #70a1ff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.ce_plugin_image--select_button:hover{
|
||||||
|
color: #8da8dc;
|
||||||
|
}
|
446
plugins/images/images.js
Normal file
446
plugins/images/images.js
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
/**
|
||||||
|
* Image plugin for codex-editor
|
||||||
|
* @author CodeX Team <team@ifmo.su>
|
||||||
|
*
|
||||||
|
* @version 0.0.2
|
||||||
|
*/
|
||||||
|
var ceImage = {
|
||||||
|
|
||||||
|
elementClasses : {
|
||||||
|
|
||||||
|
ce_image : 'ce-image',
|
||||||
|
uploadedImage : {
|
||||||
|
centered : 'ce-plugin-image__uploaded--centered',
|
||||||
|
stretched : 'ce-plugin-image__uploaded--stretched',
|
||||||
|
},
|
||||||
|
stretch : 'ce_block--stretched',
|
||||||
|
imageCaption : 'ce-plugin-image__caption',
|
||||||
|
imageWrapper : 'ce-plugin-image__wrapper',
|
||||||
|
formHolder : 'ce-plugin-image__holder',
|
||||||
|
uploadButton : 'ce-plugin-image__button',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Default path to redactors images */
|
||||||
|
path : '/upload/redactor_images/',
|
||||||
|
|
||||||
|
make : function ( data ) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we can't find image or we've got some problems with image path, we show plugin uploader
|
||||||
|
*/
|
||||||
|
if (!data || !data.file.url) {
|
||||||
|
|
||||||
|
holder = ceImage.ui.formView();
|
||||||
|
holder.classList.add(ceImage.elementClasses.ce_image);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ( data.isStretch !== 'true') {
|
||||||
|
holder = ceImage.ui.imageView(data, ceImage.elementClasses.uploadedImage.centered, 'false');
|
||||||
|
} else {
|
||||||
|
holder = ceImage.ui.imageView(data, ceImage.elementClasses.uploadedImage.stretched, 'true');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings panel content
|
||||||
|
* @return {Element} element contains all settings
|
||||||
|
*/
|
||||||
|
makeSettings : function () {
|
||||||
|
|
||||||
|
var holder = document.createElement('DIV'),
|
||||||
|
caption = document.createElement('SPAN'),
|
||||||
|
types = {
|
||||||
|
centered : 'По центру',
|
||||||
|
stretched : 'На всю ширину',
|
||||||
|
},
|
||||||
|
selectTypeButton;
|
||||||
|
|
||||||
|
/** Add holder classname */
|
||||||
|
holder.className = 'ce_plugin_image--settings';
|
||||||
|
|
||||||
|
/** Add settings helper caption */
|
||||||
|
caption.textContent = 'Настройки плагина';
|
||||||
|
caption.className = 'ce_plugin_image--caption';
|
||||||
|
|
||||||
|
holder.appendChild(caption);
|
||||||
|
|
||||||
|
/** Now add type selectors */
|
||||||
|
for (var type in types){
|
||||||
|
|
||||||
|
selectTypeButton = document.createElement('SPAN');
|
||||||
|
|
||||||
|
selectTypeButton.textContent = types[type];
|
||||||
|
selectTypeButton.className = 'ce_plugin_image--select_button';
|
||||||
|
|
||||||
|
this.addSelectTypeClickListener(selectTypeButton, type);
|
||||||
|
|
||||||
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addSelectTypeClickListener : function(el, type) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function() {
|
||||||
|
|
||||||
|
ceImage.selectTypeClicked(type);
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
selectTypeClicked : function(type) {
|
||||||
|
|
||||||
|
var current = cEditor.content.currentNode,
|
||||||
|
image = ceImage.ui.getImage(current),
|
||||||
|
wrapper = current.querySelector('.' + ceImage.elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
/** Clear classList */
|
||||||
|
current.className = '';
|
||||||
|
image.className = '';
|
||||||
|
|
||||||
|
/** Add important first-level class ce_block */
|
||||||
|
current.classList.add(cEditor.ui.className.BLOCK_CLASSNAME);
|
||||||
|
|
||||||
|
if (type === 'stretched') {
|
||||||
|
|
||||||
|
image.classList.add(ceImage.elementClasses.uploadedImage.stretched);
|
||||||
|
current.classList.add(ceImage.elementClasses.stretch);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = true;
|
||||||
|
|
||||||
|
} else if (type === 'centered') {
|
||||||
|
|
||||||
|
image.classList.add(ceImage.elementClasses.uploadedImage.centered);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function( data ) {
|
||||||
|
|
||||||
|
return this.make(data);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
save : function ( block ) {
|
||||||
|
|
||||||
|
var data = block[0],
|
||||||
|
image = ceImage.ui.getImage(data),
|
||||||
|
caption = data.querySelector('.' + ceImage.elementClasses.imageCaption);
|
||||||
|
|
||||||
|
var json = {
|
||||||
|
type : 'image',
|
||||||
|
data : {
|
||||||
|
background : false,
|
||||||
|
border : false,
|
||||||
|
isStretch : data.dataset.stretched,
|
||||||
|
file : {
|
||||||
|
url : image.src,
|
||||||
|
bigUrl : null,
|
||||||
|
width : image.width,
|
||||||
|
height : image.height,
|
||||||
|
additionalData :null,
|
||||||
|
},
|
||||||
|
caption : caption.textContent,
|
||||||
|
cover : null,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadButtonClicked : function(event) {
|
||||||
|
|
||||||
|
var success = ceImage.photoUploadingCallbacks.success,
|
||||||
|
error = ceImage.photoUploadingCallbacks.error;
|
||||||
|
|
||||||
|
/** Define callbacks */
|
||||||
|
cEditor.transport.selectAndUpload({
|
||||||
|
success,
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
pastedImageURL : function(event) {
|
||||||
|
|
||||||
|
var clipboardData = event.clipboardData || window.clipboardData,
|
||||||
|
pastedData = clipboardData.getData('Text'),
|
||||||
|
block = event.target.parentNode;
|
||||||
|
|
||||||
|
ceImage.renderURL(pastedData, block);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
renderURL : function(pastedData, block) {
|
||||||
|
|
||||||
|
Promise.resolve()
|
||||||
|
|
||||||
|
.then(function() {
|
||||||
|
return pastedData;
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(ceImage.urlify)
|
||||||
|
|
||||||
|
.then(function(url) {
|
||||||
|
|
||||||
|
/* Show loader gif **/
|
||||||
|
// block.classList.add(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
return fetch('/editor/transport?files=' + encodeURI(url))
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
urlify : function (text) {
|
||||||
|
|
||||||
|
var urlRegex = /(https?:\/\/\S+)/g;
|
||||||
|
|
||||||
|
var links = text.match(urlRegex);
|
||||||
|
|
||||||
|
if (links) {
|
||||||
|
console.log(links[0]);
|
||||||
|
return links[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(Error("Url is not matched"));
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
ceImage.ui = {
|
||||||
|
|
||||||
|
holder : function(){
|
||||||
|
|
||||||
|
var element = document.createElement('DIV');
|
||||||
|
|
||||||
|
element.classList.add(ceImage.elementClasses.formHolder);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
input : function(){
|
||||||
|
|
||||||
|
var input = document.createElement('INPUT');
|
||||||
|
|
||||||
|
return input;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadButton : function(){
|
||||||
|
|
||||||
|
var button = document.createElement('SPAN');
|
||||||
|
|
||||||
|
button.classList.add(ceImage.elementClasses.uploadButton);
|
||||||
|
|
||||||
|
button.innerHTML = '<i class="ce-icon-picture"></i>';
|
||||||
|
|
||||||
|
return button;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} source - file path
|
||||||
|
* @param {string} style - css class
|
||||||
|
* @return {object} image - document IMG tag
|
||||||
|
*/
|
||||||
|
image : function(source, style) {
|
||||||
|
|
||||||
|
var image = document.createElement('IMG');
|
||||||
|
|
||||||
|
image.classList.add(style);
|
||||||
|
|
||||||
|
image.src = source;
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapper : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(ceImage.elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
|
||||||
|
caption : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(ceImage.elementClasses.imageCaption);
|
||||||
|
div.contentEditable = true;
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws form for image upload
|
||||||
|
*/
|
||||||
|
formView : function() {
|
||||||
|
|
||||||
|
var holder = ceImage.ui.holder(),
|
||||||
|
uploadButton = ceImage.ui.uploadButton(),
|
||||||
|
input = ceImage.ui.input();
|
||||||
|
|
||||||
|
input.placeholder = 'Paste image URL or file';
|
||||||
|
|
||||||
|
holder.appendChild(uploadButton);
|
||||||
|
holder.appendChild(input);
|
||||||
|
|
||||||
|
input.addEventListener('paste', ceImage.pastedImageURL, false);
|
||||||
|
|
||||||
|
uploadButton.addEventListener('click', ceImage.uploadButtonClicked, false );
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @param {string} imageTypeClass - plugin's style
|
||||||
|
* @param {boolean} stretched - stretched or not
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
imageView : function(data, imageTypeClass, stretched) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, imageTypeClass),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = stretched,
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTML} data - Rendered block with image
|
||||||
|
*/
|
||||||
|
getImage : function(data) {
|
||||||
|
|
||||||
|
var image = data.querySelector('.' + ceImage.elementClasses.uploadedImage.centered) ||
|
||||||
|
data.querySelector('.' + ceImage.elementClasses.uploadedImage.stretched);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
centeredImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.centered),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = 'false',
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return stretched image
|
||||||
|
*/
|
||||||
|
stretchedImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.stretched),
|
||||||
|
caption = ceImage.ui.caption(),
|
||||||
|
wrapper = ceImage.ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = 'true',
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ceImage.photoUploadingCallbacks = {
|
||||||
|
|
||||||
|
/** Photo was uploaded successfully */
|
||||||
|
success : function(result) {
|
||||||
|
|
||||||
|
var parsed = JSON.parse(result),
|
||||||
|
data,
|
||||||
|
image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preparing {Object} data to draw an image
|
||||||
|
* @uses ceImage.make method
|
||||||
|
*/
|
||||||
|
data = {
|
||||||
|
background : false,
|
||||||
|
border : false,
|
||||||
|
isStrech : false,
|
||||||
|
file : {
|
||||||
|
url : ceImage.path + 'o_' + parsed.filename,
|
||||||
|
bigUrl : null,
|
||||||
|
width : null,
|
||||||
|
height : null,
|
||||||
|
additionalData : null,
|
||||||
|
},
|
||||||
|
caption : '',
|
||||||
|
cover : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
image = ceImage.make(data);
|
||||||
|
|
||||||
|
/** Replace form to image */
|
||||||
|
var form = cEditor.content.currentNode.querySelector('.' + ceImage.elementClasses.formHolder);
|
||||||
|
|
||||||
|
cEditor.content.switchBlock(form, image, 'image');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
|
||||||
|
error : function(result) {
|
||||||
|
console.log('Choosen file is not an image or image is corrupted');
|
||||||
|
cEditor.notifications.errorThrown();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
10
plugins/instagram/instagram.css
Normal file
10
plugins/instagram/instagram.css
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.ce-redactor .instagram {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 650px;
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instagram__loader {
|
||||||
|
background: url("loading.gif") !important;
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
117
plugins/instagram/instagram.js
Normal file
117
plugins/instagram/instagram.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* Instagram plugin
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
var instagramTool = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare before usage
|
||||||
|
* Load important scripts to render embed
|
||||||
|
*/
|
||||||
|
prepare : function() {
|
||||||
|
|
||||||
|
var script = "//platform.instagram.com/en_US/embeds.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load widget
|
||||||
|
*/
|
||||||
|
codex.core.importScript(script, 'instagramAPI');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make instagram embed via Widgets method
|
||||||
|
*/
|
||||||
|
make : function(data, isInternal) {
|
||||||
|
|
||||||
|
if (!data.instagram_url)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var block = instagramTool.content.instagramBlock(data.instagram_url);
|
||||||
|
|
||||||
|
if (isInternal) {
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
|
||||||
|
/** Render block */
|
||||||
|
instagramTool.content.render(block);
|
||||||
|
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
if (!isInternal) {
|
||||||
|
instagramTool.content.render(block);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saving JSON output.
|
||||||
|
* Upload data via ajax
|
||||||
|
*/
|
||||||
|
save : function(blockContent) {
|
||||||
|
|
||||||
|
var data;
|
||||||
|
|
||||||
|
if (!blockContent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/** Example */
|
||||||
|
data = {
|
||||||
|
instagram_url: blockContent.src
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render data
|
||||||
|
*/
|
||||||
|
render : function(data) {
|
||||||
|
return instagramTool.make(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
instagramTool.content = {
|
||||||
|
|
||||||
|
render : function(content) {
|
||||||
|
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
|
||||||
|
|
||||||
|
var blockContent = codex.content.currentNode.childNodes[0];
|
||||||
|
blockContent.classList.add('instagram__loader');
|
||||||
|
|
||||||
|
window.instgrm.Embeds.process();
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
blockContent.classList.remove('instagram__loader');
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawing html content.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @returns {Element} blockquote - HTML template for Instagram Embed JS
|
||||||
|
*/
|
||||||
|
instagramBlock : function(url) {
|
||||||
|
|
||||||
|
var blockquote = codex.draw.node('BLOCKQUOTE', 'instagram-media instagram', {}),
|
||||||
|
div = codex.draw.node('DIV', '', {}),
|
||||||
|
paragraph = codex.draw.node('P', 'ce-paste__instagram--p', {}),
|
||||||
|
anchor = codex.draw.node('A', '', { href : url });
|
||||||
|
|
||||||
|
blockquote.dataset.instgrmVersion = 4;
|
||||||
|
|
||||||
|
paragraph.appendChild(anchor);
|
||||||
|
div.appendChild(paragraph);
|
||||||
|
blockquote.appendChild(div);
|
||||||
|
|
||||||
|
return blockquote;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
BIN
plugins/instagram/loading.gif
Normal file
BIN
plugins/instagram/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
86
plugins/link/link.css
Normal file
86
plugins/link/link.css
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
.ce-link {
|
||||||
|
padding: 0.7em 0 !important;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clearfix:after {
|
||||||
|
visibility: hidden;
|
||||||
|
display: block;
|
||||||
|
font-size: 0;
|
||||||
|
content: " ";
|
||||||
|
clear: both;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ceditor-tool-link-input {
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 8px 25px;
|
||||||
|
transition: background 200ms;
|
||||||
|
border-left: 3px solid #65d8b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-panel {
|
||||||
|
position: relative;
|
||||||
|
margin: 5px 0;
|
||||||
|
background: #f8f7ef;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 25px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-image {
|
||||||
|
float:right;
|
||||||
|
width: 75px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-title {
|
||||||
|
display: block;
|
||||||
|
width: 340px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
line-height: 1.2em;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-description {
|
||||||
|
display: block;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-link {
|
||||||
|
width: 360px;
|
||||||
|
font-size: 10px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgba(165,156,86,.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-loader {
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: repeating-linear-gradient(-45deg, transparent, transparent 4px, #f5f9ff 4px, #eaedef 8px) !important;
|
||||||
|
background-size: 56px 56px;
|
||||||
|
animation: loading-bar 5s infinite linear;
|
||||||
|
}
|
||||||
|
@keyframes loading-bar {
|
||||||
|
100% { background-position: -56% 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tool-link-error {
|
||||||
|
background: rgb(255, 241, 241);
|
||||||
|
color: #bf4747;
|
||||||
|
}
|
||||||
|
.tool-link-error .ceditor-tool-link-input {
|
||||||
|
border-left-color: #d86b6b
|
||||||
|
}
|
308
plugins/link/link.js
Normal file
308
plugins/link/link.js
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
/**
|
||||||
|
* Created by nostr on 29.06.16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link tool plugin
|
||||||
|
*/
|
||||||
|
var linkTool = {
|
||||||
|
|
||||||
|
defaultText : 'Insert link here ...',
|
||||||
|
ENTER_KEY : 13,
|
||||||
|
|
||||||
|
currentBlock : null,
|
||||||
|
currentInput : null,
|
||||||
|
elementClasses : {
|
||||||
|
link : "tool-link-link",
|
||||||
|
image : "tool-link-image",
|
||||||
|
title : "tool-link-title",
|
||||||
|
description : "tool-link-description",
|
||||||
|
loader : "tool-link-loader",
|
||||||
|
error : "tool-link-error"
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make initial header block
|
||||||
|
* @param {object} JSON with block data
|
||||||
|
* @return {Element} element to append
|
||||||
|
*/
|
||||||
|
makeNewBlock : function (data) {
|
||||||
|
|
||||||
|
var wrapper = linkTool.ui.mainBlock(),
|
||||||
|
tag = linkTool.ui.input();
|
||||||
|
|
||||||
|
linkTool.currentInput = tag;
|
||||||
|
|
||||||
|
wrapper.appendChild(tag);
|
||||||
|
|
||||||
|
wrapper.classList.add('ce-link');
|
||||||
|
/**
|
||||||
|
* Bind callbacks
|
||||||
|
**/
|
||||||
|
tag.addEventListener('paste', linkTool.blockPasteCallback, false);
|
||||||
|
tag.addEventListener('keydown', linkTool.blockKeyDownCallback, false);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render HTML block from JSON
|
||||||
|
*/
|
||||||
|
render : function (json) {
|
||||||
|
|
||||||
|
var block = linkTool.ui.mainBlock(),
|
||||||
|
tag = linkTool.ui.make(json);
|
||||||
|
|
||||||
|
block.classList.add('ce-link');
|
||||||
|
block.appendChild(tag);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to extract JSON data from HTML block
|
||||||
|
*/
|
||||||
|
save : function (blockContent){
|
||||||
|
|
||||||
|
var linkElement = linkTool.elementClasses.link;
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
url : blockContent.querySelector("." + linkElement).href,
|
||||||
|
shortLink : blockContent.querySelector("." + linkElement).textContent,
|
||||||
|
image : blockContent.querySelector("." + linkTool.elementClasses.image).src,
|
||||||
|
title : blockContent.querySelector("." + linkTool.elementClasses.title).textContent,
|
||||||
|
description : blockContent.querySelector("." + linkTool.elementClasses.description).textContent
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
blockPasteCallback : function (event) {
|
||||||
|
|
||||||
|
var clipboardData = event.clipboardData || window.clipboardData,
|
||||||
|
pastedData = clipboardData.getData('Text'),
|
||||||
|
block = event.target.parentNode;
|
||||||
|
|
||||||
|
linkTool.renderLink(pastedData, block);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
blockKeyDownCallback : function (event) {
|
||||||
|
|
||||||
|
var inputTag = event.target,
|
||||||
|
block = inputTag.parentNode,
|
||||||
|
url;
|
||||||
|
|
||||||
|
if ( block.classList.contains(linkTool.elementClasses.error) )
|
||||||
|
{
|
||||||
|
block.classList.remove(linkTool.elementClasses.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == linkTool.ENTER_KEY) {
|
||||||
|
|
||||||
|
url = inputTag.value;
|
||||||
|
|
||||||
|
linkTool.renderLink(url, block);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo move request-url to accepted settings
|
||||||
|
*/
|
||||||
|
renderLink : function (url, block) {
|
||||||
|
|
||||||
|
Promise.resolve()
|
||||||
|
|
||||||
|
.then(function () {
|
||||||
|
return linkTool.urlify(url);
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (url) {
|
||||||
|
|
||||||
|
/* Show loader gif **/
|
||||||
|
block.classList.add(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
return fetch('/club/linkInfo?url=' + encodeURI(url));
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
|
if (response.status == "200"){
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return Error("Invalid response status: %o", response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (json) {
|
||||||
|
console.log(json);
|
||||||
|
linkTool.composeLinkPreview(json, block);
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function(error) {
|
||||||
|
|
||||||
|
/* Hide loader gif **/
|
||||||
|
block.classList.remove(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
block.classList.add(linkTool.elementClasses.error);
|
||||||
|
|
||||||
|
codex.core.log('Error while doing things with link paste: %o', 'error', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
urlify : function (text) {
|
||||||
|
|
||||||
|
var urlRegex = /(https?:\/\/\S+)/g;
|
||||||
|
|
||||||
|
var links = text.match(urlRegex);
|
||||||
|
|
||||||
|
if (links) {
|
||||||
|
return links[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(Error("Url is not matched"));
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
composeLinkPreview : function (json, currentBlock) {
|
||||||
|
|
||||||
|
if (json == {}) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var previewBlock = linkTool.ui.make(json);
|
||||||
|
|
||||||
|
linkTool.currentInput.remove();
|
||||||
|
|
||||||
|
currentBlock.appendChild(previewBlock);
|
||||||
|
|
||||||
|
currentBlock.classList.remove(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
linkTool.ui = {
|
||||||
|
|
||||||
|
make : function (json) {
|
||||||
|
|
||||||
|
var wrapper = this.wrapper(),
|
||||||
|
siteImage = this.image(json.image, linkTool.elementClasses.image),
|
||||||
|
siteTitle = this.title(json.title),
|
||||||
|
siteDescription = this.description(json.description),
|
||||||
|
siteLink = this.link(json.url, json.url);
|
||||||
|
|
||||||
|
wrapper.appendChild(siteImage);
|
||||||
|
wrapper.appendChild(siteTitle);
|
||||||
|
wrapper.appendChild(siteLink);
|
||||||
|
wrapper.appendChild(siteDescription);
|
||||||
|
|
||||||
|
siteTitle.contentEditable = true;
|
||||||
|
siteDescription.contentEditable = true;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
mainBlock : function () {
|
||||||
|
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
|
||||||
|
wrapper.classList.add("ceditor-tool-link");
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
input : function () {
|
||||||
|
|
||||||
|
var inputTag = document.createElement('input');
|
||||||
|
|
||||||
|
inputTag.classList.add("ceditor-tool-link-input");
|
||||||
|
|
||||||
|
inputTag.placeholder = linkTool.defaultText;
|
||||||
|
|
||||||
|
inputTag.contentEditable = false;
|
||||||
|
|
||||||
|
return inputTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapper : function () {
|
||||||
|
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
|
||||||
|
wrapper.className += 'tool-link-panel clearfix';
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
image : function (imageSrc, imageClass) {
|
||||||
|
|
||||||
|
var imageTag = document.createElement('img');
|
||||||
|
|
||||||
|
imageTag.classList.add(imageClass);
|
||||||
|
|
||||||
|
imageTag.setAttribute('src', imageSrc);
|
||||||
|
|
||||||
|
return imageTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
link : function (linkUrl, linkText) {
|
||||||
|
|
||||||
|
var linkTag = document.createElement('a');
|
||||||
|
|
||||||
|
linkTag.classList.add(linkTool.elementClasses.link);
|
||||||
|
|
||||||
|
linkTag.href = linkUrl;
|
||||||
|
|
||||||
|
linkTag.target = "_blank";
|
||||||
|
|
||||||
|
linkTag.innerText = linkText;
|
||||||
|
|
||||||
|
return linkTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
title : function (titleText) {
|
||||||
|
|
||||||
|
var titleTag = document.createElement('div');
|
||||||
|
|
||||||
|
titleTag.classList.add("tool-link-content", linkTool.elementClasses.title);
|
||||||
|
|
||||||
|
titleTag.innerHTML = titleText;
|
||||||
|
|
||||||
|
return titleTag;
|
||||||
|
},
|
||||||
|
|
||||||
|
description : function (descriptionText) {
|
||||||
|
|
||||||
|
var descriptionTag = document.createElement('div');
|
||||||
|
|
||||||
|
descriptionTag.classList.add("tool-link-content", linkTool.elementClasses.description);
|
||||||
|
|
||||||
|
descriptionTag.innerHTML = descriptionText;
|
||||||
|
|
||||||
|
return descriptionTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
37
plugins/list/list.css
Normal file
37
plugins/list/list.css
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
.ce-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: .5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce_plugin_list--settings{
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce_plugin_list--select_button{
|
||||||
|
display: block;
|
||||||
|
color: #306ac7;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
.ce_plugin_list--select_button:not(:last-of-type){
|
||||||
|
margin-bottom: 0.9em;
|
||||||
|
}
|
||||||
|
.ce_plugin_list--select_button:hover{
|
||||||
|
color: #a1b4ec;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* List style settigns icons
|
||||||
|
*/
|
||||||
|
.ce_plugin_list--select_button i{
|
||||||
|
margin-right: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-list li{
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ebeef3;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: .5em;
|
||||||
|
padding: .5em;
|
||||||
|
list-style-position: outside;
|
||||||
|
margin-left: 1.1em;
|
||||||
|
}
|
157
plugins/list/list.js
Normal file
157
plugins/list/list.js
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/**
|
||||||
|
* Code Plugin\
|
||||||
|
* Creates code tag and adds content to this tag
|
||||||
|
*/
|
||||||
|
var listTool = {
|
||||||
|
|
||||||
|
baseClass : "tool-list",
|
||||||
|
elementClasses : {
|
||||||
|
li : "tool-list-li"
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make initial header block
|
||||||
|
* @param {object} JSON with block data
|
||||||
|
* @return {Element} element to append
|
||||||
|
*/
|
||||||
|
make : function () {
|
||||||
|
|
||||||
|
var tag = listTool.ui.make(),
|
||||||
|
li = listTool.ui.block("li", "tool-link-li");
|
||||||
|
|
||||||
|
var br = document.createElement("br");
|
||||||
|
|
||||||
|
li.appendChild(br);
|
||||||
|
tag.appendChild(li);
|
||||||
|
|
||||||
|
tag.classList.add('ce-list');
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render HTML block from JSON
|
||||||
|
*/
|
||||||
|
render : function (data) {
|
||||||
|
|
||||||
|
var type = data.type == 'ordered' ? 'OL' : 'UL',
|
||||||
|
tag = listTool.ui.make(type);
|
||||||
|
|
||||||
|
tag.classList.add('ce-list');
|
||||||
|
|
||||||
|
data.items.forEach(function (element, index, array) {
|
||||||
|
|
||||||
|
var newLi = listTool.ui.block("li", listTool.elementClasses.li);
|
||||||
|
|
||||||
|
newLi.innerHTML = element;
|
||||||
|
|
||||||
|
tag.dataset.type = data.type;
|
||||||
|
tag.appendChild(newLi);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to extract JSON data from HTML block
|
||||||
|
*/
|
||||||
|
save : function (blockContent){
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
type : null,
|
||||||
|
items : [],
|
||||||
|
};
|
||||||
|
|
||||||
|
for(var index = 0; index < blockContent.childNodes.length; index++)
|
||||||
|
data.items[index] = blockContent.childNodes[index].textContent;
|
||||||
|
|
||||||
|
data.type = blockContent.dataset.type;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
makeSettings : function(data) {
|
||||||
|
|
||||||
|
var holder = document.createElement('DIV'),
|
||||||
|
selectTypeButton;
|
||||||
|
|
||||||
|
/** Add holder classname */
|
||||||
|
holder.className = 'ce_plugin_list--settings';
|
||||||
|
|
||||||
|
var orderedButton = listTool.ui.button("ordered"),
|
||||||
|
unorderedButton = listTool.ui.button("unordered");
|
||||||
|
|
||||||
|
orderedButton.addEventListener('click', function (event) {
|
||||||
|
listTool.changeBlockStyle(event, 'ol');
|
||||||
|
codex.toolbar.settings.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
unorderedButton.addEventListener('click', function (event) {
|
||||||
|
listTool.changeBlockStyle(event, 'ul');
|
||||||
|
codex.toolbar.settings.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.appendChild(orderedButton);
|
||||||
|
holder.appendChild(unorderedButton);
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
changeBlockStyle : function (event, blockType) {
|
||||||
|
|
||||||
|
var currentBlock = codex.content.currentNode,
|
||||||
|
newEditable = listTool.ui.make(blockType),
|
||||||
|
oldEditable = currentBlock.querySelector("[contenteditable]");
|
||||||
|
|
||||||
|
newEditable.dataset.type = blockType;
|
||||||
|
newEditable.innerHTML = oldEditable.innerHTML;
|
||||||
|
newEditable.classList.add('ce-list');
|
||||||
|
|
||||||
|
codex.content.switchBlock(currentBlock, newEditable, 'list');
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
listTool.ui = {
|
||||||
|
|
||||||
|
make : function (blockType) {
|
||||||
|
|
||||||
|
var wrapper = this.block(blockType || 'UL', listTool.baseClass);
|
||||||
|
|
||||||
|
wrapper.dataset.type = 'ul';
|
||||||
|
wrapper.contentEditable = true;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
block : function (blockType, blockClass) {
|
||||||
|
|
||||||
|
var block = document.createElement(blockType);
|
||||||
|
|
||||||
|
if ( blockClass ) block.classList.add(blockClass);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
button : function (buttonType) {
|
||||||
|
|
||||||
|
var types = {
|
||||||
|
unordered : '<i class="ce-icon-list-bullet"></i>Обычный список',
|
||||||
|
ordered : '<i class="ce-icon-list-numbered"></i>Нумерованный список'
|
||||||
|
},
|
||||||
|
button = document.createElement('SPAN');
|
||||||
|
|
||||||
|
button.innerHTML = types[buttonType];
|
||||||
|
|
||||||
|
button.className = 'ce_plugin_list--select_button';
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
};
|
28
plugins/paragraph/paragraph.css
Normal file
28
plugins/paragraph/paragraph.css
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* Empty paragraph placeholder
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ce-paragraph {
|
||||||
|
padding: 0.7em 0 !important;
|
||||||
|
line-height: 1.7em;
|
||||||
|
}
|
||||||
|
.ce-paragraph:empty::before{
|
||||||
|
content : attr(data-placeholder);
|
||||||
|
color: #818BA1;
|
||||||
|
opacity: .7;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
.ce-paragraph:focus::before{
|
||||||
|
opacity: .1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ce-paragraph p {
|
||||||
|
margin: 1.2em 0;
|
||||||
|
}
|
||||||
|
.ce-paragraph p:first-of-type{
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.ce-paragraph p:last-of-type{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
69
plugins/paragraph/paragraph.js
Normal file
69
plugins/paragraph/paragraph.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* Paragraph Plugin\
|
||||||
|
* Creates P tag and adds content to this tag
|
||||||
|
*/
|
||||||
|
// var tools = require('./../plugins');
|
||||||
|
|
||||||
|
var paragraphTool = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make initial header block
|
||||||
|
* @param {object} JSON with block data
|
||||||
|
* @return {Element} element to append
|
||||||
|
*/
|
||||||
|
make : function (data) {
|
||||||
|
|
||||||
|
var tag = document.createElement('DIV');
|
||||||
|
|
||||||
|
tag.classList.add('ce-paragraph');
|
||||||
|
|
||||||
|
if (data && data.text) {
|
||||||
|
tag.innerHTML = data.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.contentEditable = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if plugin need to add placeholder
|
||||||
|
* tag.setAttribute('data-placeholder', 'placehoder');
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @uses Paste tool callback.
|
||||||
|
* Function analyzes pasted data
|
||||||
|
* If pasted URL from instagram, twitter or Image
|
||||||
|
* it renders via Social widgets content or uploads image and uses Image tool to render
|
||||||
|
*/
|
||||||
|
tag.addEventListener('paste', codex.tools.paste.callbacks.pasted, false);
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render HTML block from JSON
|
||||||
|
*/
|
||||||
|
render : function (data) {
|
||||||
|
|
||||||
|
return paragraphTool.make(data);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to extract JSON data from HTML block
|
||||||
|
*/
|
||||||
|
save : function (blockContent){
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
text : null,
|
||||||
|
format: "html",
|
||||||
|
introText: '<<same>>'
|
||||||
|
};
|
||||||
|
|
||||||
|
data.text = blockContent.innerHTML;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
BIN
plugins/paste/loading.gif
Normal file
BIN
plugins/paste/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
17
plugins/paste/paste.css
Normal file
17
plugins/paste/paste.css
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
.ce-paste {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #55818c;
|
||||||
|
}
|
||||||
|
.ce-paste:empty::before {
|
||||||
|
content : attr(data-placeholder);
|
||||||
|
color: #5e6475;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-paste:focus::before{
|
||||||
|
opacity: .1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-paste-plugin__loader {
|
||||||
|
background: url("loading.gif") !important;
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
225
plugins/paste/paste.js
Normal file
225
plugins/paste/paste.js
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/**
|
||||||
|
* Paste plugin.
|
||||||
|
*
|
||||||
|
* Listens on paste event and pastes content from:
|
||||||
|
* - Instagram
|
||||||
|
* - Twitter
|
||||||
|
* - VK
|
||||||
|
* - Facebook
|
||||||
|
* - Image
|
||||||
|
* - External Link
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
*
|
||||||
|
* Main tool settings.
|
||||||
|
*/
|
||||||
|
var pasteTool = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make elements to insert or switch
|
||||||
|
*
|
||||||
|
* @uses Core codex.draw module
|
||||||
|
*/
|
||||||
|
pasteTool.ui = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload image by URL
|
||||||
|
*
|
||||||
|
* @uses codex Image tool
|
||||||
|
* @param filename
|
||||||
|
* @returns {Element}
|
||||||
|
*/
|
||||||
|
uploadedImage : function(filename) {
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
background: false,
|
||||||
|
border: false,
|
||||||
|
isStretch: false,
|
||||||
|
file: {
|
||||||
|
url: "upload/redactor_images/" + filename,
|
||||||
|
bigUrl: "upload/redactor_images/" + filename,
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
additionalData: "null"
|
||||||
|
},
|
||||||
|
caption: '',
|
||||||
|
cover: null
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Using Image plugin make method */
|
||||||
|
var image = codex.tools.image.make(data);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Callbacks
|
||||||
|
*/
|
||||||
|
pasteTool.callbacks = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves data
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
pasted : function(event) {
|
||||||
|
|
||||||
|
var clipBoardData = event.clipboardData || window.clipboardData,
|
||||||
|
content = clipBoardData.getData('Text');
|
||||||
|
|
||||||
|
pasteTool.callbacks.analize(content);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analizes pated string and calls necessary method
|
||||||
|
*/
|
||||||
|
analize : function(string) {
|
||||||
|
|
||||||
|
var regexTemplates = {
|
||||||
|
image : /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*\.(?:jpe?g|gif|png))(?:\?([^#]*))?(?:#(.*))?/i,
|
||||||
|
instagram : new RegExp("http?.+instagram.com\/p?."),
|
||||||
|
twitter : new RegExp("http?.+twitter.com?.+\/"),
|
||||||
|
facebook : /https?.+facebook.+\/\d+\?/,
|
||||||
|
vk : /https?.+vk?.com\/feed\?w=wall\d+_\d+/,
|
||||||
|
},
|
||||||
|
|
||||||
|
image = regexTemplates.image.test(string),
|
||||||
|
instagram = regexTemplates.instagram.exec(string),
|
||||||
|
twitter = regexTemplates.twitter.exec(string),
|
||||||
|
facebook = regexTemplates.facebook.test(string),
|
||||||
|
vk = regexTemplates.vk.test(string);
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
|
||||||
|
pasteTool.callbacks.uploadImage(string);
|
||||||
|
|
||||||
|
} else if (instagram) {
|
||||||
|
|
||||||
|
pasteTool.callbacks.instagramMedia(instagram);
|
||||||
|
|
||||||
|
} else if (twitter) {
|
||||||
|
|
||||||
|
pasteTool.callbacks.twitterMedia(twitter);
|
||||||
|
|
||||||
|
} else if (facebook) {
|
||||||
|
|
||||||
|
pasteTool.callbacks.facebookMedia(string);
|
||||||
|
|
||||||
|
} else if (vk) {
|
||||||
|
|
||||||
|
pasteTool.callbacks.vkMedia(string);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct upload
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
uploadImage : function(path) {
|
||||||
|
|
||||||
|
var ajaxUrl = location.protocol + '//' + location.hostname + ':32769',
|
||||||
|
file,
|
||||||
|
image,
|
||||||
|
current = codex.content.currentNode,
|
||||||
|
beforeSend,
|
||||||
|
success_callback;
|
||||||
|
|
||||||
|
/** When image is uploaded to redactors folder */
|
||||||
|
success_callback = function(data) {
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
return;
|
||||||
|
var file = JSON.parse(data);
|
||||||
|
image = pasteTool.ui.uploadedImage(file.filename);
|
||||||
|
codex.content.switchBlock(current, image, 'image');
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Before sending XMLHTTP request */
|
||||||
|
beforeSend = function() {
|
||||||
|
var content = current.querySelector('.ce-block__content');
|
||||||
|
content.classList.add('ce-plugin-image__loader');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Preparing data for XMLHTTP */
|
||||||
|
var data = {
|
||||||
|
url: '/club/fetchImage',
|
||||||
|
type: "POST",
|
||||||
|
data : {
|
||||||
|
url: path
|
||||||
|
},
|
||||||
|
beforeSend : beforeSend,
|
||||||
|
success : success_callback
|
||||||
|
};
|
||||||
|
|
||||||
|
codex.core.ajax(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback for instagram url's
|
||||||
|
* Using instagram Embed Widgete to render
|
||||||
|
* @uses Instagram tool
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
instagramMedia : function(url) {
|
||||||
|
|
||||||
|
var fullUrl = url.input,
|
||||||
|
data;
|
||||||
|
|
||||||
|
|
||||||
|
data = {
|
||||||
|
instagram_url: fullUrl
|
||||||
|
};
|
||||||
|
|
||||||
|
codex.tools.instagram.make(data, true);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback for tweets
|
||||||
|
* Using Twittter Widget to render
|
||||||
|
* @uses Twitter tool
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
twitterMedia : function(url) {
|
||||||
|
|
||||||
|
var fullUrl = url.input,
|
||||||
|
tweetId,
|
||||||
|
arr,
|
||||||
|
data;
|
||||||
|
|
||||||
|
arr = fullUrl.split('/');
|
||||||
|
tweetId = arr.pop();
|
||||||
|
|
||||||
|
/** Example */
|
||||||
|
data = {
|
||||||
|
media:true,
|
||||||
|
conversation:false,
|
||||||
|
user:{
|
||||||
|
profile_image_url:"http:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
||||||
|
profile_image_url_https:"https:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
||||||
|
screen_name:"Niketas",
|
||||||
|
name:"Никита Лихачёв"
|
||||||
|
},
|
||||||
|
id: tweetId,
|
||||||
|
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
|
||||||
|
created_at:"Tue Jun 28 14:09:12 +0000 2016",
|
||||||
|
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
|
||||||
|
caption:"Caption"
|
||||||
|
};
|
||||||
|
|
||||||
|
codex.tools.twitter.make(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
BIN
plugins/quote/img/codex.png
Normal file
BIN
plugins/quote/img/codex.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
plugins/quote/img/upload.png
Normal file
BIN
plugins/quote/img/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
193
plugins/quote/quote.css
Normal file
193
plugins/quote/quote.css
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
.ce_plugin_quote--select_button{
|
||||||
|
display: block;
|
||||||
|
color: #306ac7;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
.ce_plugin_quote--select_button:not(:last-of-type){
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.ce_plugin_quote--select_button:hover{
|
||||||
|
color: #a1b4ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Quote Styles */
|
||||||
|
|
||||||
|
.quoteStyle-withCaption--author:empty {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
.quoteStyle-withCaption--author {
|
||||||
|
|
||||||
|
margin: 0 100px 2em !important;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 1.16em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
line-height: 1.5em;
|
||||||
|
|
||||||
|
}
|
||||||
|
.quoteStyle-simple--text,
|
||||||
|
.quoteStyle-withCaption--blockquote,
|
||||||
|
.quoteStyle-withPhoto--quote {
|
||||||
|
font-size: 1.04em;
|
||||||
|
line-height: 1.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-simple--text {
|
||||||
|
padding: 1.2em 2.1em;
|
||||||
|
margin: 2.5em 2em;
|
||||||
|
background: #FBFBFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withCaption--blockquote {
|
||||||
|
margin: 0;
|
||||||
|
padding: 1.5em 2.0em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withCaption--blockquote:focus,
|
||||||
|
.quoteStyle-withCaption--author:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-simple--text:empty::before,
|
||||||
|
.quoteStyle-withCaption--blockquote:empty::before,
|
||||||
|
.quoteStyle-withPhoto--quote:empty::before
|
||||||
|
{
|
||||||
|
content : 'Введите цитату';
|
||||||
|
color: #818BA1;
|
||||||
|
opacity: 0.7;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withCaption--author:empty::before
|
||||||
|
{
|
||||||
|
content : 'Введите имя автора';
|
||||||
|
font-weight: normal;
|
||||||
|
color: #a1a5b3;;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--author:empty::before {
|
||||||
|
content : 'Введите имя автора';
|
||||||
|
color: #000;
|
||||||
|
opacity: .8;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-simple--text:focus::before,
|
||||||
|
.quoteStyle-withCaption--blockquote:focus::before,
|
||||||
|
.quoteStyle-withPhoto--quote:focus::before
|
||||||
|
{
|
||||||
|
opacity: .1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withCaption--author:focus::before,
|
||||||
|
.quoteStyle-withPhoto--author:focus::before
|
||||||
|
{
|
||||||
|
opacity: .1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Quote with photo */
|
||||||
|
.ce_redactor .quoteStyle-withPhoto--wrapper {
|
||||||
|
margin: 0;
|
||||||
|
padding: 4.5em 3.6em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--photo {
|
||||||
|
width: 92px;
|
||||||
|
height: 92px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 92px;
|
||||||
|
border-radius: 3px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
border: 1px solid #ebeef3;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--photo:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background: #F0F3F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--photo:hover::after {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.authorsPhoto {
|
||||||
|
height: 110%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.authorsPhoto-wrapper {
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--photo .ce-icon-picture {
|
||||||
|
font-family: "codex_editor";
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #d5dbea;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--photo:hover{
|
||||||
|
background: #fdfeff;
|
||||||
|
border-color: #c1c4cc;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--photo:hover .ce-icon-picture {
|
||||||
|
color: #2b3142;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--author {
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--job {
|
||||||
|
color: #818BA1;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--job:empty::before {
|
||||||
|
content : 'Введите должность автора';
|
||||||
|
color: #A5ABBC;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--job:focus::before {
|
||||||
|
opacity: .1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quoteStyle-withPhoto--quote {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
line-height: 1.82em;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New styles
|
||||||
|
*/
|
||||||
|
.ce-quote{
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--author,
|
||||||
|
.quoteStyle-withPhoto--job,
|
||||||
|
.quoteStyle-withPhoto--quote{
|
||||||
|
background: #fff;
|
||||||
|
padding: .6em .8em;
|
||||||
|
border: 1px solid #ebeef3;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.quoteStyle-withPhoto--quote{
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Current select-type button
|
||||||
|
*/
|
||||||
|
.ce-quote-settings--selected{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
446
plugins/quote/quote.js
Normal file
446
plugins/quote/quote.js
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
/**
|
||||||
|
* Codex Team
|
||||||
|
* @author Khaydarov Murod
|
||||||
|
*/
|
||||||
|
|
||||||
|
var quoteTools = {
|
||||||
|
|
||||||
|
/** Default path to redactors images */
|
||||||
|
path : '/upload/redactor_images/',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default quote style
|
||||||
|
*/
|
||||||
|
defaultStyle : 'withPhoto',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make Quote from JSON datasets
|
||||||
|
*/
|
||||||
|
makeBlockToAppend : function(data) {
|
||||||
|
|
||||||
|
var tag;
|
||||||
|
|
||||||
|
if (data && data.size) {
|
||||||
|
|
||||||
|
data.style = 'withPhoto';
|
||||||
|
|
||||||
|
switch (data.style) {
|
||||||
|
case 'simple':
|
||||||
|
tag = quoteTools.makeSimpleQuote(data);
|
||||||
|
break;
|
||||||
|
case 'withCaption':
|
||||||
|
tag = quoteTools.makeQuoteWithCaption(data);
|
||||||
|
break;
|
||||||
|
case 'withPhoto':
|
||||||
|
tag = quoteTools.makeQuoteWithPhoto(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var settings = {
|
||||||
|
style : 'withPhoto',
|
||||||
|
text : '',
|
||||||
|
author : '',
|
||||||
|
job : '',
|
||||||
|
photo : ''
|
||||||
|
};
|
||||||
|
|
||||||
|
tag = quoteTools.makeQuoteWithPhoto(settings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function(data) {
|
||||||
|
return quoteTools.makeBlockToAppend(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
save : function(blockContent) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts JSON quote data from HTML block
|
||||||
|
* @param {Text} text, {Text} author, {Object} photo
|
||||||
|
*/
|
||||||
|
var parsedblock = quoteTools.parseBlockQuote(blockContent);
|
||||||
|
data = {
|
||||||
|
style : parsedblock.style,
|
||||||
|
text : parsedblock.text,
|
||||||
|
author : parsedblock.author,
|
||||||
|
job : parsedblock.job,
|
||||||
|
photo : parsedblock.photo,
|
||||||
|
"format":"html",
|
||||||
|
"cite": parsedblock.author,
|
||||||
|
"size": "small"
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
|
makeSettings : function(data) {
|
||||||
|
|
||||||
|
var holder = document.createElement('DIV'),
|
||||||
|
types = {
|
||||||
|
simple : 'Простая цитата',
|
||||||
|
withCaption : 'Цитата с подписью',
|
||||||
|
withPhoto : 'Цитата с фото и ФИО'
|
||||||
|
},
|
||||||
|
selectTypeButton;
|
||||||
|
|
||||||
|
/** Add holder classname */
|
||||||
|
holder.className = quoteTools.styles.settings.holder;
|
||||||
|
|
||||||
|
/** Now add type selectors */
|
||||||
|
for (var type in types){
|
||||||
|
|
||||||
|
selectTypeButton = document.createElement('SPAN');
|
||||||
|
|
||||||
|
selectTypeButton.textContent = types[type];
|
||||||
|
selectTypeButton.className = quoteTools.styles.settings.buttons;
|
||||||
|
|
||||||
|
selectTypeButton.dataset.style = type;
|
||||||
|
|
||||||
|
if ( type == quoteTools.defaultStyle ){
|
||||||
|
selectTypeButton.classList.add(quoteTools.styles.settings.selectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// var quoteStyle = quoteTools.selectTypeQuoteStyle(type);
|
||||||
|
|
||||||
|
selectTypeButton.addEventListener('click', quoteTools.changeStyleClicked, false);
|
||||||
|
// quoteTools.addSelectTypeClickListener(selectTypeButton, quoteStyle);
|
||||||
|
|
||||||
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
changeStyleClicked : function() {
|
||||||
|
|
||||||
|
var changeStyleButton = this,
|
||||||
|
quote = codex.content.currentNode.querySelector('.' + quoteTools.styles.ce_quote),
|
||||||
|
newStyle = changeStyleButton.dataset.style,
|
||||||
|
styleSelectors = this.parentNode.childNodes;
|
||||||
|
|
||||||
|
quote.dataset.quoteStyle = newStyle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark selected style button
|
||||||
|
*/
|
||||||
|
for (var i = styleSelectors.length - 1; i >= 0; i--) {
|
||||||
|
styleSelectors[i].classList.remove(quoteTools.styles.settings.selectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.classList.add(quoteTools.styles.settings.selectedType);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
selectTypeQuoteStyle : function(type) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose Quote style to replace
|
||||||
|
*/
|
||||||
|
switch (type) {
|
||||||
|
case 'simple':
|
||||||
|
quoteStyleFunction = quoteTools.makeSimpleQuote;
|
||||||
|
break;
|
||||||
|
case 'withCaption':
|
||||||
|
quoteStyleFunction = quoteTools.makeQuoteWithCaption;
|
||||||
|
break;
|
||||||
|
case 'withPhoto':
|
||||||
|
quoteStyleFunction = quoteTools.makeQuoteWithPhoto;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quoteStyleFunction;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
addSelectTypeClickListener : function(el, quoteStyle) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function () {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsing currentNode to JSON.
|
||||||
|
*/
|
||||||
|
var parsedOldQuote = quoteTools.parseBlockQuote(),
|
||||||
|
newStyledQuote = quoteStyle(parsedOldQuote);
|
||||||
|
|
||||||
|
var wrapper = codex.content.composeNewBlock(newStyledQuote, 'quote');
|
||||||
|
wrapper.appendChild(newStyledQuote);
|
||||||
|
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, newStyledQuote, 'quote');
|
||||||
|
|
||||||
|
/** Close settings after replacing */
|
||||||
|
codex.toolbar.settings.close();
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
makeSimpleQuote : function(data) {
|
||||||
|
|
||||||
|
var wrapper = quoteTools.ui.makeBlock('BLOCKQUOTE', [quoteTools.styles.simple.text, quoteTools.styles.quoteText]);
|
||||||
|
|
||||||
|
wrapper.innerHTML = data.text || '';
|
||||||
|
|
||||||
|
wrapper.dataset.quoteStyle = 'simple';
|
||||||
|
wrapper.classList.add(quoteTools.styles.ce_quote);
|
||||||
|
wrapper.contentEditable = 'true';
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
makeQuoteWithCaption : function(data) {
|
||||||
|
|
||||||
|
var wrapper = quoteTools.ui.blockquote(),
|
||||||
|
text = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withCaption.blockquote, quoteTools.styles.quoteText]),
|
||||||
|
author = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withCaption.author, quoteTools.styles.quoteAuthor]);
|
||||||
|
|
||||||
|
/* make text block ontentEditable */
|
||||||
|
text.contentEditable = 'true';
|
||||||
|
|
||||||
|
text.innerHTML = data.text;
|
||||||
|
|
||||||
|
/* make Author contentEditable */
|
||||||
|
author.contentEditable = 'true';
|
||||||
|
|
||||||
|
author.textContent = data.cite;
|
||||||
|
|
||||||
|
/* Appending created components */
|
||||||
|
wrapper.dataset.quoteStyle = 'withCaption';
|
||||||
|
wrapper.classList.add(quoteTools.styles.ce_quote);
|
||||||
|
|
||||||
|
wrapper.appendChild(text);
|
||||||
|
wrapper.appendChild(author);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
makeQuoteWithPhoto : function(data) {
|
||||||
|
|
||||||
|
var wrapper = quoteTools.ui.blockquote(),
|
||||||
|
photo = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.photo]),
|
||||||
|
author = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.author, quoteTools.styles.quoteAuthor]),
|
||||||
|
job = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.job, quoteTools.styles.authorsJob]),
|
||||||
|
quote = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.quote, quoteTools.styles.quoteText]);
|
||||||
|
|
||||||
|
/* Default Image src */
|
||||||
|
if (!data.photo) {
|
||||||
|
|
||||||
|
var icon = quoteTools.ui.makeBlock('SPAN', ['ce-icon-picture']);
|
||||||
|
photo.appendChild(icon);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var authorsPhoto = quoteTools.ui.img(quoteTools.styles.authorsPhoto);
|
||||||
|
authorsPhoto.src = data.photo;
|
||||||
|
|
||||||
|
photo.classList.add(quoteTools.styles.authorsPhotoWrapper);
|
||||||
|
photo.appendChild(authorsPhoto);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
photo.addEventListener('click', quoteTools.fileUploadClicked, false);
|
||||||
|
|
||||||
|
/* make author block contentEditable */
|
||||||
|
author.contentEditable = 'true';
|
||||||
|
author.textContent = data.cite;
|
||||||
|
|
||||||
|
/* Author's position and job */
|
||||||
|
job.contentEditable = 'true';
|
||||||
|
job.textContent = data.job;
|
||||||
|
|
||||||
|
var authorsWrapper = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.authorHolder]);
|
||||||
|
authorsWrapper.appendChild(author);
|
||||||
|
authorsWrapper.appendChild(job);
|
||||||
|
|
||||||
|
/* make quote text contentEditable */
|
||||||
|
quote.contentEditable = 'true';
|
||||||
|
quote.innerHTML = data.text;
|
||||||
|
|
||||||
|
wrapper.classList.add(quoteTools.styles.ce_quote);
|
||||||
|
wrapper.classList.add(quoteTools.styles.withPhoto.wrapper);
|
||||||
|
wrapper.dataset.quoteStyle = 'withPhoto';
|
||||||
|
|
||||||
|
wrapper.appendChild(quote);
|
||||||
|
wrapper.appendChild(photo);
|
||||||
|
wrapper.appendChild(authorsWrapper);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
parseBlockQuote : function(block) {
|
||||||
|
|
||||||
|
var currentNode = block || codex.content.currentNode,
|
||||||
|
photo = currentNode.getElementsByTagName('img')[0],
|
||||||
|
author = currentNode.querySelector('.' + quoteTools.styles.quoteAuthor),
|
||||||
|
job = currentNode.querySelector('.' + quoteTools.styles.authorsJob),
|
||||||
|
quote ;
|
||||||
|
|
||||||
|
/** Simple quote text placed in Blockquote tag*/
|
||||||
|
if ( currentNode.dataset.quoteStyle == 'simple' )
|
||||||
|
quote = currentNode.innerHTML;
|
||||||
|
else
|
||||||
|
quote = currentNode.querySelector('.' + quoteTools.styles.quoteText).innerHTML;
|
||||||
|
|
||||||
|
if (job)
|
||||||
|
job = job.textContent;
|
||||||
|
|
||||||
|
if (author)
|
||||||
|
author = author.textContent;
|
||||||
|
|
||||||
|
if (photo)
|
||||||
|
photo = photo.src;
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
style : currentNode.dataset.quoteStyle,
|
||||||
|
text : quote,
|
||||||
|
author : author,
|
||||||
|
job : job,
|
||||||
|
photo : photo,
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
|
fileUploadClicked : function() {
|
||||||
|
|
||||||
|
var success = quoteTools.photoUploadingCallbacks.success,
|
||||||
|
error = quoteTools.photoUploadingCallbacks.error;
|
||||||
|
|
||||||
|
codex.transport.selectAndUpload({
|
||||||
|
success,
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
quoteTools.styles = {
|
||||||
|
|
||||||
|
ce_quote : 'ce-quote',
|
||||||
|
quoteText : 'ce_quote--text',
|
||||||
|
quoteAuthor : 'ce_quote--author',
|
||||||
|
authorsJob : 'ce_quote--job',
|
||||||
|
authorsPhoto : 'authorsPhoto',
|
||||||
|
authorsPhotoWrapper : 'authorsPhoto-wrapper',
|
||||||
|
|
||||||
|
simple : {
|
||||||
|
text : 'quoteStyle-simple--text'
|
||||||
|
},
|
||||||
|
|
||||||
|
withCaption : {
|
||||||
|
blockquote : 'quoteStyle-withCaption--blockquote',
|
||||||
|
author : 'quoteStyle-withCaption--author'
|
||||||
|
},
|
||||||
|
|
||||||
|
withPhoto : {
|
||||||
|
photo : 'quoteStyle-withPhoto--photo',
|
||||||
|
author : 'quoteStyle-withPhoto--author',
|
||||||
|
job : 'quoteStyle-withPhoto--job',
|
||||||
|
quote : 'quoteStyle-withPhoto--quote',
|
||||||
|
wrapper : 'quoteStyle-withPhoto--wrapper',
|
||||||
|
authorHolder : 'quoteStyle-withPhoto--authorWrapper'
|
||||||
|
},
|
||||||
|
|
||||||
|
settings : {
|
||||||
|
holder : 'ce_plugin_quote--settings',
|
||||||
|
caption : 'ce_plugin_quote--caption',
|
||||||
|
buttons : 'ce_plugin_quote--select_button',
|
||||||
|
selectedType : 'ce-quote-settings--selected'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quoteTools.ui = {
|
||||||
|
|
||||||
|
wrapper : function($classList) {
|
||||||
|
|
||||||
|
var el = document.createElement('DIV');
|
||||||
|
|
||||||
|
el.classList.add($classList);
|
||||||
|
|
||||||
|
return el;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
blockquote : function() {
|
||||||
|
|
||||||
|
var el = document.createElement('BLOCKQUOTE');
|
||||||
|
|
||||||
|
return el;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
img : function(attribute) {
|
||||||
|
var imageTag = document.createElement('IMG');
|
||||||
|
imageTag.classList.add(attribute);
|
||||||
|
|
||||||
|
return imageTag;
|
||||||
|
},
|
||||||
|
|
||||||
|
makeBlock : function(tag, classList) {
|
||||||
|
|
||||||
|
var el = document.createElement(tag);
|
||||||
|
|
||||||
|
|
||||||
|
if ( classList ) {
|
||||||
|
|
||||||
|
for( var i = 0; i < classList.length; i++)
|
||||||
|
el.className += ' ' + classList[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
quoteTools.photoUploadingCallbacks = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Success callbacks for uploaded photo.
|
||||||
|
* Replace upload icon with uploaded photo
|
||||||
|
*/
|
||||||
|
success : function(result) {
|
||||||
|
|
||||||
|
var parsed = JSON.parse(result),
|
||||||
|
filename = parsed.filename,
|
||||||
|
uploadImageWrapper = codex.content.currentNode.querySelector('.' + quoteTools.styles.withPhoto.photo),
|
||||||
|
authorsPhoto = quoteTools.ui.img(quoteTools.styles.authorsPhoto);
|
||||||
|
|
||||||
|
authorsPhoto.src = quoteTools.path + 'b_' + filename;
|
||||||
|
|
||||||
|
/** Remove icon from image wrapper */
|
||||||
|
uploadImageWrapper.innerHTML = '';
|
||||||
|
|
||||||
|
/** Appending uploaded image */
|
||||||
|
uploadImageWrapper.classList.add(quoteTools.styles.authorsPhotoWrapper);
|
||||||
|
uploadImageWrapper.appendChild(authorsPhoto);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
|
||||||
|
error : function(result) {
|
||||||
|
|
||||||
|
console.log('Can\'t upload an image');
|
||||||
|
codex.notifications.errorThrown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
BIN
plugins/twitter/loading.gif
Normal file
BIN
plugins/twitter/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
8
plugins/twitter/twitter.css
Normal file
8
plugins/twitter/twitter.css
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.ce-redactor .twitter-tweet {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.twitter__loader {
|
||||||
|
background: url("loading.gif") !important;
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
90
plugins/twitter/twitter.js
Normal file
90
plugins/twitter/twitter.js
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* Twitter plugin
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
var twitterTool = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare twitter scripts
|
||||||
|
*/
|
||||||
|
prepare : function() {
|
||||||
|
|
||||||
|
var script = "//platform.twitter.com/widgets.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load script
|
||||||
|
*/
|
||||||
|
codex.core.importScript(script, 'twitterAPI');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
make : function(data) {
|
||||||
|
|
||||||
|
if (!data.id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
twitterTool.content.twitter(data.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
save : function(blockContent) {
|
||||||
|
|
||||||
|
var data;
|
||||||
|
|
||||||
|
data = {
|
||||||
|
media:true,
|
||||||
|
conversation:false,
|
||||||
|
user:{
|
||||||
|
profile_image_url:"http:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
||||||
|
profile_image_url_https:"https:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
||||||
|
screen_name:"Niketas",
|
||||||
|
name:"Никита Лихачёв"
|
||||||
|
},
|
||||||
|
id: blockContent.dataset.tweetId,
|
||||||
|
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
|
||||||
|
created_at:"Tue Jun 28 14:09:12 +0000 2016",
|
||||||
|
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
|
||||||
|
caption:"Caption"
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function(data) {
|
||||||
|
return twitterTool.make(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
twitterTool.content = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Twitter render method appends content after block
|
||||||
|
* @param tweetId
|
||||||
|
*/
|
||||||
|
twitter : function(tweetId) {
|
||||||
|
|
||||||
|
var tweet = twitterTool.content.twitterBlock();
|
||||||
|
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, tweet, 'twitter');
|
||||||
|
|
||||||
|
var blockContent = codex.content.currentNode.childNodes[0];
|
||||||
|
blockContent.classList.add('twitter__loader');
|
||||||
|
|
||||||
|
window.twttr.widgets.createTweet(tweetId, blockContent);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
blockContent.classList.remove('twitter__loader');
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
/** Remove empty DIV */
|
||||||
|
blockContent.childNodes[0].remove();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
twitterBlock : function() {
|
||||||
|
var block = codex.draw.node('DIV', '', {});
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
};
|
|
@ -13,11 +13,12 @@ var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
entry: {
|
entry: {
|
||||||
codex: "./index"
|
"whatwg-fetch": "whatwg-fetch",
|
||||||
|
"codex-editor": "./index"
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: "./codex.editor.js",
|
filename: "[name].js",
|
||||||
library: ["codex", "editor"]
|
library: ["codex"]
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: true,
|
watch: true,
|
||||||
|
|
510
whatwg-fetch.js
Normal file
510
whatwg-fetch.js
Normal file
|
@ -0,0 +1,510 @@
|
||||||
|
var codex =
|
||||||
|
/******/ (function(modules) { // webpackBootstrap
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var installedModules = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ if(installedModules[moduleId])
|
||||||
|
/******/ return installedModules[moduleId].exports;
|
||||||
|
/******/
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
/******/ exports: {},
|
||||||
|
/******/ id: moduleId,
|
||||||
|
/******/ loaded: false
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Flag the module as loaded
|
||||||
|
/******/ module.loaded = true;
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/
|
||||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||||
|
/******/ __webpack_require__.m = modules;
|
||||||
|
/******/
|
||||||
|
/******/ // expose the module cache
|
||||||
|
/******/ __webpack_require__.c = installedModules;
|
||||||
|
/******/
|
||||||
|
/******/ // __webpack_public_path__
|
||||||
|
/******/ __webpack_require__.p = "";
|
||||||
|
/******/
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ return __webpack_require__(0);
|
||||||
|
/******/ })
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ ([
|
||||||
|
/* 0 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
(function(self) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (self.fetch) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var support = {
|
||||||
|
searchParams: 'URLSearchParams' in self,
|
||||||
|
iterable: 'Symbol' in self && 'iterator' in Symbol,
|
||||||
|
blob: 'FileReader' in self && 'Blob' in self && (function() {
|
||||||
|
try {
|
||||||
|
new Blob()
|
||||||
|
return true
|
||||||
|
} catch(e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
formData: 'FormData' in self,
|
||||||
|
arrayBuffer: 'ArrayBuffer' in self
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support.arrayBuffer) {
|
||||||
|
var viewClasses = [
|
||||||
|
'[object Int8Array]',
|
||||||
|
'[object Uint8Array]',
|
||||||
|
'[object Uint8ClampedArray]',
|
||||||
|
'[object Int16Array]',
|
||||||
|
'[object Uint16Array]',
|
||||||
|
'[object Int32Array]',
|
||||||
|
'[object Uint32Array]',
|
||||||
|
'[object Float32Array]',
|
||||||
|
'[object Float64Array]'
|
||||||
|
]
|
||||||
|
|
||||||
|
var isDataView = function(obj) {
|
||||||
|
return obj && DataView.prototype.isPrototypeOf(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
var isArrayBufferView = ArrayBuffer.isView || function(obj) {
|
||||||
|
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeName(name) {
|
||||||
|
if (typeof name !== 'string') {
|
||||||
|
name = String(name)
|
||||||
|
}
|
||||||
|
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
|
||||||
|
throw new TypeError('Invalid character in header field name')
|
||||||
|
}
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeValue(value) {
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
value = String(value)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a destructive iterator for the value list
|
||||||
|
function iteratorFor(items) {
|
||||||
|
var iterator = {
|
||||||
|
next: function() {
|
||||||
|
var value = items.shift()
|
||||||
|
return {done: value === undefined, value: value}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support.iterable) {
|
||||||
|
iterator[Symbol.iterator] = function() {
|
||||||
|
return iterator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
function Headers(headers) {
|
||||||
|
this.map = {}
|
||||||
|
|
||||||
|
if (headers instanceof Headers) {
|
||||||
|
headers.forEach(function(value, name) {
|
||||||
|
this.append(name, value)
|
||||||
|
}, this)
|
||||||
|
|
||||||
|
} else if (headers) {
|
||||||
|
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
||||||
|
this.append(name, headers[name])
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.append = function(name, value) {
|
||||||
|
name = normalizeName(name)
|
||||||
|
value = normalizeValue(value)
|
||||||
|
var oldValue = this.map[name]
|
||||||
|
this.map[name] = oldValue ? oldValue+','+value : value
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype['delete'] = function(name) {
|
||||||
|
delete this.map[normalizeName(name)]
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.get = function(name) {
|
||||||
|
name = normalizeName(name)
|
||||||
|
return this.has(name) ? this.map[name] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.has = function(name) {
|
||||||
|
return this.map.hasOwnProperty(normalizeName(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.set = function(name, value) {
|
||||||
|
this.map[normalizeName(name)] = normalizeValue(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.forEach = function(callback, thisArg) {
|
||||||
|
for (var name in this.map) {
|
||||||
|
if (this.map.hasOwnProperty(name)) {
|
||||||
|
callback.call(thisArg, this.map[name], name, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.keys = function() {
|
||||||
|
var items = []
|
||||||
|
this.forEach(function(value, name) { items.push(name) })
|
||||||
|
return iteratorFor(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.values = function() {
|
||||||
|
var items = []
|
||||||
|
this.forEach(function(value) { items.push(value) })
|
||||||
|
return iteratorFor(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
Headers.prototype.entries = function() {
|
||||||
|
var items = []
|
||||||
|
this.forEach(function(value, name) { items.push([name, value]) })
|
||||||
|
return iteratorFor(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support.iterable) {
|
||||||
|
Headers.prototype[Symbol.iterator] = Headers.prototype.entries
|
||||||
|
}
|
||||||
|
|
||||||
|
function consumed(body) {
|
||||||
|
if (body.bodyUsed) {
|
||||||
|
return Promise.reject(new TypeError('Already read'))
|
||||||
|
}
|
||||||
|
body.bodyUsed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileReaderReady(reader) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
reader.onload = function() {
|
||||||
|
resolve(reader.result)
|
||||||
|
}
|
||||||
|
reader.onerror = function() {
|
||||||
|
reject(reader.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBlobAsArrayBuffer(blob) {
|
||||||
|
var reader = new FileReader()
|
||||||
|
var promise = fileReaderReady(reader)
|
||||||
|
reader.readAsArrayBuffer(blob)
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBlobAsText(blob) {
|
||||||
|
var reader = new FileReader()
|
||||||
|
var promise = fileReaderReady(reader)
|
||||||
|
reader.readAsText(blob)
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
function readArrayBufferAsText(buf) {
|
||||||
|
var view = new Uint8Array(buf)
|
||||||
|
var chars = new Array(view.length)
|
||||||
|
|
||||||
|
for (var i = 0; i < view.length; i++) {
|
||||||
|
chars[i] = String.fromCharCode(view[i])
|
||||||
|
}
|
||||||
|
return chars.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
function bufferClone(buf) {
|
||||||
|
if (buf.slice) {
|
||||||
|
return buf.slice(0)
|
||||||
|
} else {
|
||||||
|
var view = new Uint8Array(buf.byteLength)
|
||||||
|
view.set(new Uint8Array(buf))
|
||||||
|
return view.buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Body() {
|
||||||
|
this.bodyUsed = false
|
||||||
|
|
||||||
|
this._initBody = function(body) {
|
||||||
|
this._bodyInit = body
|
||||||
|
if (!body) {
|
||||||
|
this._bodyText = ''
|
||||||
|
} else if (typeof body === 'string') {
|
||||||
|
this._bodyText = body
|
||||||
|
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
||||||
|
this._bodyBlob = body
|
||||||
|
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
||||||
|
this._bodyFormData = body
|
||||||
|
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
||||||
|
this._bodyText = body.toString()
|
||||||
|
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
||||||
|
this._bodyArrayBuffer = bufferClone(body.buffer)
|
||||||
|
// IE 10-11 can't handle a DataView body.
|
||||||
|
this._bodyInit = new Blob([this._bodyArrayBuffer])
|
||||||
|
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
||||||
|
this._bodyArrayBuffer = bufferClone(body)
|
||||||
|
} else {
|
||||||
|
throw new Error('unsupported BodyInit type')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.headers.get('content-type')) {
|
||||||
|
if (typeof body === 'string') {
|
||||||
|
this.headers.set('content-type', 'text/plain;charset=UTF-8')
|
||||||
|
} else if (this._bodyBlob && this._bodyBlob.type) {
|
||||||
|
this.headers.set('content-type', this._bodyBlob.type)
|
||||||
|
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
||||||
|
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support.blob) {
|
||||||
|
this.blob = function() {
|
||||||
|
var rejected = consumed(this)
|
||||||
|
if (rejected) {
|
||||||
|
return rejected
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._bodyBlob) {
|
||||||
|
return Promise.resolve(this._bodyBlob)
|
||||||
|
} else if (this._bodyArrayBuffer) {
|
||||||
|
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
||||||
|
} else if (this._bodyFormData) {
|
||||||
|
throw new Error('could not read FormData body as blob')
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(new Blob([this._bodyText]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.arrayBuffer = function() {
|
||||||
|
if (this._bodyArrayBuffer) {
|
||||||
|
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
|
||||||
|
} else {
|
||||||
|
return this.blob().then(readBlobAsArrayBuffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.text = function() {
|
||||||
|
var rejected = consumed(this)
|
||||||
|
if (rejected) {
|
||||||
|
return rejected
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._bodyBlob) {
|
||||||
|
return readBlobAsText(this._bodyBlob)
|
||||||
|
} else if (this._bodyArrayBuffer) {
|
||||||
|
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
||||||
|
} else if (this._bodyFormData) {
|
||||||
|
throw new Error('could not read FormData body as text')
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(this._bodyText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support.formData) {
|
||||||
|
this.formData = function() {
|
||||||
|
return this.text().then(decode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.json = function() {
|
||||||
|
return this.text().then(JSON.parse)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP methods whose capitalization should be normalized
|
||||||
|
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
|
||||||
|
|
||||||
|
function normalizeMethod(method) {
|
||||||
|
var upcased = method.toUpperCase()
|
||||||
|
return (methods.indexOf(upcased) > -1) ? upcased : method
|
||||||
|
}
|
||||||
|
|
||||||
|
function Request(input, options) {
|
||||||
|
options = options || {}
|
||||||
|
var body = options.body
|
||||||
|
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
this.url = input
|
||||||
|
} else {
|
||||||
|
if (input.bodyUsed) {
|
||||||
|
throw new TypeError('Already read')
|
||||||
|
}
|
||||||
|
this.url = input.url
|
||||||
|
this.credentials = input.credentials
|
||||||
|
if (!options.headers) {
|
||||||
|
this.headers = new Headers(input.headers)
|
||||||
|
}
|
||||||
|
this.method = input.method
|
||||||
|
this.mode = input.mode
|
||||||
|
if (!body && input._bodyInit != null) {
|
||||||
|
body = input._bodyInit
|
||||||
|
input.bodyUsed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.credentials = options.credentials || this.credentials || 'omit'
|
||||||
|
if (options.headers || !this.headers) {
|
||||||
|
this.headers = new Headers(options.headers)
|
||||||
|
}
|
||||||
|
this.method = normalizeMethod(options.method || this.method || 'GET')
|
||||||
|
this.mode = options.mode || this.mode || null
|
||||||
|
this.referrer = null
|
||||||
|
|
||||||
|
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
||||||
|
throw new TypeError('Body not allowed for GET or HEAD requests')
|
||||||
|
}
|
||||||
|
this._initBody(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.prototype.clone = function() {
|
||||||
|
return new Request(this, { body: this._bodyInit })
|
||||||
|
}
|
||||||
|
|
||||||
|
function decode(body) {
|
||||||
|
var form = new FormData()
|
||||||
|
body.trim().split('&').forEach(function(bytes) {
|
||||||
|
if (bytes) {
|
||||||
|
var split = bytes.split('=')
|
||||||
|
var name = split.shift().replace(/\+/g, ' ')
|
||||||
|
var value = split.join('=').replace(/\+/g, ' ')
|
||||||
|
form.append(decodeURIComponent(name), decodeURIComponent(value))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHeaders(rawHeaders) {
|
||||||
|
var headers = new Headers()
|
||||||
|
rawHeaders.split('\r\n').forEach(function(line) {
|
||||||
|
var parts = line.split(':')
|
||||||
|
var key = parts.shift().trim()
|
||||||
|
if (key) {
|
||||||
|
var value = parts.join(':').trim()
|
||||||
|
headers.append(key, value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return headers
|
||||||
|
}
|
||||||
|
|
||||||
|
Body.call(Request.prototype)
|
||||||
|
|
||||||
|
function Response(bodyInit, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = 'default'
|
||||||
|
this.status = 'status' in options ? options.status : 200
|
||||||
|
this.ok = this.status >= 200 && this.status < 300
|
||||||
|
this.statusText = 'statusText' in options ? options.statusText : 'OK'
|
||||||
|
this.headers = new Headers(options.headers)
|
||||||
|
this.url = options.url || ''
|
||||||
|
this._initBody(bodyInit)
|
||||||
|
}
|
||||||
|
|
||||||
|
Body.call(Response.prototype)
|
||||||
|
|
||||||
|
Response.prototype.clone = function() {
|
||||||
|
return new Response(this._bodyInit, {
|
||||||
|
status: this.status,
|
||||||
|
statusText: this.statusText,
|
||||||
|
headers: new Headers(this.headers),
|
||||||
|
url: this.url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Response.error = function() {
|
||||||
|
var response = new Response(null, {status: 0, statusText: ''})
|
||||||
|
response.type = 'error'
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
var redirectStatuses = [301, 302, 303, 307, 308]
|
||||||
|
|
||||||
|
Response.redirect = function(url, status) {
|
||||||
|
if (redirectStatuses.indexOf(status) === -1) {
|
||||||
|
throw new RangeError('Invalid status code')
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(null, {status: status, headers: {location: url}})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Headers = Headers
|
||||||
|
self.Request = Request
|
||||||
|
self.Response = Response
|
||||||
|
|
||||||
|
self.fetch = function(input, init) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var request = new Request(input, init)
|
||||||
|
var xhr = new XMLHttpRequest()
|
||||||
|
|
||||||
|
xhr.onload = function() {
|
||||||
|
var options = {
|
||||||
|
status: xhr.status,
|
||||||
|
statusText: xhr.statusText,
|
||||||
|
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
||||||
|
}
|
||||||
|
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
|
||||||
|
var body = 'response' in xhr ? xhr.response : xhr.responseText
|
||||||
|
resolve(new Response(body, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onerror = function() {
|
||||||
|
reject(new TypeError('Network request failed'))
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.ontimeout = function() {
|
||||||
|
reject(new TypeError('Network request failed'))
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.open(request.method, request.url, true)
|
||||||
|
|
||||||
|
if (request.credentials === 'include') {
|
||||||
|
xhr.withCredentials = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('responseType' in xhr && support.blob) {
|
||||||
|
xhr.responseType = 'blob'
|
||||||
|
}
|
||||||
|
|
||||||
|
request.headers.forEach(function(value, name) {
|
||||||
|
xhr.setRequestHeader(name, value)
|
||||||
|
})
|
||||||
|
|
||||||
|
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
self.fetch.polyfill = true
|
||||||
|
})(typeof self !== 'undefined' ? self : this);
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }
|
||||||
|
/******/ ]);
|
||||||
|
//# sourceMappingURL=whatwg-fetch.js.map
|
1
whatwg-fetch.js.map
Normal file
1
whatwg-fetch.js.map
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue