mirror of
https://github.com/codex-team/editor.js
synced 2024-06-26 09:20:07 +02:00
merged
This commit is contained in:
commit
2f2f508659
|
@ -722,6 +722,13 @@ cEditor.callback = {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LEFT or UP not at the beginning
|
||||||
|
*/
|
||||||
|
if ( selection.anchorOffset !== 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Saving caret after keydown event happend */
|
/** Saving caret after keydown event happend */
|
||||||
cEditor.caret.save();
|
cEditor.caret.save();
|
||||||
|
|
||||||
|
@ -732,37 +739,43 @@ cEditor.callback = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find deepest child node
|
* Do nothing if caret is not at the beginning of first child
|
||||||
* Iterate child nodes and find First DEEPEST node
|
|
||||||
* We need it to check caret positon (it must be at the begining)
|
|
||||||
*/
|
*/
|
||||||
focusedNodeHolder = focusedNodeHolder || focusedNode;
|
var caretInFirstChild = false,
|
||||||
|
caretAtTheBeginning = false;
|
||||||
|
|
||||||
if (focusedNodeHolder.childNodes.length !== 0) {
|
var editableElement = focusedNode.querySelector('[contenteditable]'),
|
||||||
|
firstChild,
|
||||||
|
deepestTextnode;
|
||||||
|
|
||||||
var focusedTextNode = '';
|
if (!editableElement) {
|
||||||
|
cEditor.core.log('Can not find editable element in current block: %o', 'warn', focusedNode);
|
||||||
if (focusedNodeHolder.childNodes){
|
|
||||||
/** Looking from the first child */
|
|
||||||
focusedTextNode = cEditor.content.getDeepestTextNodeFromPosition(focusedNodeHolder, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* When we click "UP" or "LEFT", caret behaviour is as default.
|
|
||||||
* We should check caret position before we transmit/switch the block.
|
|
||||||
*/
|
|
||||||
if ( selection.anchorOffset !== 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We can't switch block till caret is not at the begining of first node and has zero offset
|
|
||||||
*/
|
|
||||||
if ( (cEditor.caret.offset !== 0 || cEditor.caret.focusedNodeIndex !== 0) && focusedNodeHolder.childNodes.length !== 0 ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cEditor.caret.setToPreviousBlock(block);
|
firstChild = editableElement.childNodes[0];
|
||||||
|
|
||||||
|
if (cEditor.core.isDomNode(firstChild)) {
|
||||||
|
|
||||||
|
deepestTextnode = cEditor.content.getDeepestTextNodeFromPosition(firstChild, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
deepestTextnode = firstChild;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
caretInFirstChild = selection.anchorNode == deepestTextnode;
|
||||||
|
caretAtTheBeginning = cEditor.caret.offset === 0;
|
||||||
|
|
||||||
|
console.log("каретка в первом узле: %o", caretInFirstChild);
|
||||||
|
console.log("каретка в начале первого узла: %o", caretAtTheBeginning);
|
||||||
|
|
||||||
|
if ( caretInFirstChild && caretAtTheBeginning ) {
|
||||||
|
|
||||||
|
cEditor.caret.setToPreviousBlock(focusedNode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1288,7 +1301,7 @@ cEditor.caret = {
|
||||||
|
|
||||||
console.log("nextBlock: %o", nextBlock);
|
console.log("nextBlock: %o", nextBlock);
|
||||||
|
|
||||||
nextBlockEditableElement = nextBlock.querySelector('[contenteditable], [contenteditable="true"]');
|
nextBlockEditableElement = nextBlock.querySelector('[contenteditable]');
|
||||||
|
|
||||||
console.log("nextBlockEditableElement: %o", nextBlockEditableElement);
|
console.log("nextBlockEditableElement: %o", nextBlockEditableElement);
|
||||||
|
|
||||||
|
@ -1302,6 +1315,9 @@ cEditor.caret = {
|
||||||
cEditor.content.workingNodeChanged(block.nextSibling);
|
cEditor.content.workingNodeChanged(block.nextSibling);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo передалать на prevBlock.querySelector('[contenteditable]') по аналогии с setToNextBlock
|
||||||
|
*/
|
||||||
setToPreviousBlock : function(block) {
|
setToPreviousBlock : function(block) {
|
||||||
|
|
||||||
if ( !block.previousSibling ) {
|
if ( !block.previousSibling ) {
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="plugins/ceditor-tool-link.css" />
|
|
||||||
|
<link rel="stylesheet" href="plugins/ceditor-tool-link/ceditor-tool-link.css" />
|
||||||
<link rel="stylesheet" href="plugins/ceditor-tool-quote/ceditor-tool-quote.css" />
|
<link rel="stylesheet" href="plugins/ceditor-tool-quote/ceditor-tool-quote.css" />
|
||||||
<link rel="stylesheet" href="plugins/images/plugin.css" />
|
<link rel="stylesheet" href="plugins/images/plugin.css" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body style="padding: 100px">
|
<body style="padding: 100px">
|
||||||
|
|
||||||
|
@ -168,7 +170,7 @@
|
||||||
link : {
|
link : {
|
||||||
'linkUrl' : 'http://google.com',
|
'linkUrl' : 'http://google.com',
|
||||||
'linkText' : 'google.com',
|
'linkText' : 'google.com',
|
||||||
'image' : 'http://i1.kym-cdn.com/photos/images/facebook/000/002/110/longcat.jpg',
|
'image' : 'http://2.bp.blogspot.com/-7bZ5EziliZQ/VynIS9F7OAI/AAAAAAAASQ0/BJFntXCAntstZe6hQuo5KTrhi5Dyz9yHgCK4B/s1600/googlelogo_color_200x200.png',
|
||||||
'title' : 'Google',
|
'title' : 'Google',
|
||||||
'description' : 'Поисковик, поисковик, проч.'
|
'description' : 'Поисковик, поисковик, проч.'
|
||||||
}
|
}
|
||||||
|
@ -268,6 +270,6 @@
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="plugins/ceditor-tool-link.js"></script>
|
<script src="plugins/ceditor-tool-link/ceditor-tool-link.js"></script>
|
||||||
<script src="plugins/ceditor-tool-quote/ceditor-tool-quote.js"></script>
|
<script src="plugins/ceditor-tool-quote/ceditor-tool-quote.js"></script>
|
||||||
<script src="plugins/images/plugin.js"></script>
|
<script src="plugins/images/plugin.js"></script>
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 0;
|
border: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 12px;
|
||||||
|
transition: background 200ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-link-panel {
|
.tool-link-panel {
|
||||||
|
@ -57,3 +61,23 @@
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: rgba(165,156,86,.8);
|
color: rgba(165,156,86,.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tool-link-loader {
|
||||||
|
|
||||||
|
background: url("loading.gif") !important;
|
||||||
|
opacity: 0.1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-link-error {
|
||||||
|
|
||||||
|
/*background: repeating-linear-gradient(*/
|
||||||
|
/*45deg,*/
|
||||||
|
/*#bc320e,*/
|
||||||
|
/*#606dbc 10px,*/
|
||||||
|
/*#465298 10px,*/
|
||||||
|
/*#465298 20px*/
|
||||||
|
/*);*/
|
||||||
|
background: rgba(255, 0, 0, 0.9);
|
||||||
|
|
||||||
|
}
|
|
@ -8,13 +8,17 @@
|
||||||
var linkTool = {
|
var linkTool = {
|
||||||
|
|
||||||
defaultText : 'Insert link here ...',
|
defaultText : 'Insert link here ...',
|
||||||
|
ENTER_KEY : 13,
|
||||||
|
|
||||||
currentBlock : null,
|
currentBlock : null,
|
||||||
currentInput : null,
|
currentInput : null,
|
||||||
elementClasses : {
|
elementClasses : {
|
||||||
link : "tool-link-link",
|
link : "tool-link-link",
|
||||||
image : "tool-link-image",
|
image : "tool-link-image",
|
||||||
title : "tool-link-title",
|
title : "tool-link-title",
|
||||||
description : "tool-link-description"
|
description : "tool-link-description",
|
||||||
|
loader : "tool-link-loader",
|
||||||
|
error : "tool-link-error"
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +40,8 @@ var linkTool = {
|
||||||
|
|
||||||
tag.addEventListener('paste', linkTool.blockPasteCallback, false);
|
tag.addEventListener('paste', linkTool.blockPasteCallback, false);
|
||||||
|
|
||||||
|
tag.addEventListener('keydown', linkTool.blockKeyDownCallback, false);
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -82,19 +88,53 @@ var linkTool = {
|
||||||
|
|
||||||
blockPasteCallback : function (event) {
|
blockPasteCallback : function (event) {
|
||||||
|
|
||||||
clipboardData = event.clipboardData || window.clipboardData;
|
var clipboardData = event.clipboardData || window.clipboardData,
|
||||||
|
pastedData = clipboardData.getData('Text'),
|
||||||
|
block = event.target.parentNode;
|
||||||
|
|
||||||
pastedData = clipboardData.getData('Text');
|
linkTool.renderLink(pastedData, block);
|
||||||
|
|
||||||
var block = event.target.parentNode;
|
event.stopPropagation();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
blockKeyDownCallback : function (event) {
|
||||||
|
|
||||||
|
var inputTag = event.target,
|
||||||
|
block = inputTag.parentNode;
|
||||||
|
|
||||||
|
if (block.classList.contains(linkTool.elementClasses.error))
|
||||||
|
{
|
||||||
|
block.classList.remove(linkTool.elementClasses.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == linkTool.ENTER_KEY) {
|
||||||
|
|
||||||
|
var url = inputTag.value;
|
||||||
|
|
||||||
|
linkTool.renderLink(url, block);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
renderLink : function (url, block) {
|
||||||
|
|
||||||
Promise.resolve()
|
Promise.resolve()
|
||||||
|
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return linkTool.urlify(pastedData)
|
return linkTool.urlify(url)
|
||||||
})
|
})
|
||||||
|
|
||||||
.then(fetch('http://ajax.ru/link'))
|
.then(function (url) {
|
||||||
|
|
||||||
|
/* Show loader gif **/
|
||||||
|
block.classList.add(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
return fetch('/server/?url=' + encodeURI(url));
|
||||||
|
})
|
||||||
|
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|
||||||
|
@ -105,13 +145,7 @@ var linkTool = {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
return {
|
return Error("Invalid response status: %o", response);
|
||||||
'linkUrl' : 'http://yandex.ru',
|
|
||||||
'linkText' : 'yandex.ru',
|
|
||||||
'image' : 'https://yastatic.net/morda-logo/i/apple-touch-icon/ru-76x76.png',
|
|
||||||
'title' : 'Яндекс',
|
|
||||||
'description' : 'Сайт, поисковик, проч.'
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +156,12 @@ var linkTool = {
|
||||||
})
|
})
|
||||||
|
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
|
|
||||||
|
/* Hide loader gif **/
|
||||||
|
block.classList.remove(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
|
block.classList.add(linkTool.elementClasses.error);
|
||||||
|
|
||||||
cEditor.core.log('Error while doing things with link paste: %o', 'error', error);
|
cEditor.core.log('Error while doing things with link paste: %o', 'error', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,7 +177,7 @@ var linkTool = {
|
||||||
return links[0];
|
return links[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return Promise.reject(Error("Url is not matched"));
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -155,6 +195,8 @@ var linkTool = {
|
||||||
|
|
||||||
currentBlock.appendChild(previewBlock);
|
currentBlock.appendChild(previewBlock);
|
||||||
|
|
||||||
|
currentBlock.classList.remove(linkTool.elementClasses.loader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -164,7 +206,7 @@ linkTool.ui = {
|
||||||
make : function (json) {
|
make : function (json) {
|
||||||
|
|
||||||
var wrapper = this.wrapper(),
|
var wrapper = this.wrapper(),
|
||||||
siteImage = this.image(json.image),
|
siteImage = this.image(json.image, linkTool.elementClasses.image),
|
||||||
siteTitle = this.title(json.title),
|
siteTitle = this.title(json.title),
|
||||||
siteDescription = this.description(json.description),
|
siteDescription = this.description(json.description),
|
||||||
siteLink = this.link(json.linkUrl, json.linkText);
|
siteLink = this.link(json.linkUrl, json.linkText);
|
||||||
|
@ -190,15 +232,15 @@ linkTool.ui = {
|
||||||
|
|
||||||
input : function () {
|
input : function () {
|
||||||
|
|
||||||
var inpitTag = document.createElement('input');
|
var inputTag = document.createElement('input');
|
||||||
|
|
||||||
inpitTag.classList += "ceditor-tool-link-input";
|
inputTag.classList += "ceditor-tool-link-input";
|
||||||
|
|
||||||
inpitTag.placeholder = linkTool.defaultText;
|
inputTag.placeholder = linkTool.defaultText;
|
||||||
|
|
||||||
inpitTag.contentEditable = false;
|
inputTag.contentEditable = false;
|
||||||
|
|
||||||
return inpitTag;
|
return inputTag;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -212,11 +254,11 @@ linkTool.ui = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
image : function (imageSrc) {
|
image : function (imageSrc, imageClass) {
|
||||||
|
|
||||||
var imageTag = document.createElement('img');
|
var imageTag = document.createElement('img');
|
||||||
|
|
||||||
imageTag.classList += linkTool.elementClasses.image;
|
imageTag.classList += imageClass;
|
||||||
|
|
||||||
imageTag.setAttribute('src', imageSrc);
|
imageTag.setAttribute('src', imageSrc);
|
||||||
|
|
||||||
|
@ -260,7 +302,7 @@ linkTool.ui = {
|
||||||
descriptionTag.innerHTML = descriptionText;
|
descriptionTag.innerHTML = descriptionText;
|
||||||
|
|
||||||
return descriptionTag;
|
return descriptionTag;
|
||||||
}
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
BIN
plugins/ceditor-tool-link/loading.gif
Normal file
BIN
plugins/ceditor-tool-link/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
95
server/index.php
Normal file
95
server/index.php
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function file_get_contents_curl($url)
|
||||||
|
{
|
||||||
|
$ch = curl_init();
|
||||||
|
|
||||||
|
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||||
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||||
|
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36');
|
||||||
|
|
||||||
|
$data = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_url()
|
||||||
|
{
|
||||||
|
if (!isset($_GET['url']))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $_GET['url'];
|
||||||
|
|
||||||
|
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_meta_from_html($html)
|
||||||
|
{
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
@$doc->loadHTML($html);
|
||||||
|
$nodes = $doc->getElementsByTagName('title');
|
||||||
|
|
||||||
|
$title = $nodes->item(0)->nodeValue;
|
||||||
|
$description = "";
|
||||||
|
$keywords = "";
|
||||||
|
$image = "";
|
||||||
|
|
||||||
|
$metas = $doc->getElementsByTagName('meta');
|
||||||
|
|
||||||
|
for ($i = 0; $i < $metas->length; $i++)
|
||||||
|
{
|
||||||
|
$meta = $metas->item($i);
|
||||||
|
if($meta->getAttribute('name') == 'description')
|
||||||
|
$description = $meta->getAttribute('content');
|
||||||
|
if($meta->getAttribute('name') == 'keywords')
|
||||||
|
$keywords = $meta->getAttribute('content');
|
||||||
|
if($meta->getAttribute('property')=='og:image'){
|
||||||
|
$image = $meta->getAttribute('content');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'image' => $image,
|
||||||
|
'title' => $title,
|
||||||
|
'description' => $description
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = get_url();
|
||||||
|
|
||||||
|
$url_params = parse_url($url);
|
||||||
|
|
||||||
|
if (!$url)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = file_get_contents_curl($url);
|
||||||
|
|
||||||
|
$result = get_meta_from_html($html);
|
||||||
|
|
||||||
|
$result = array_merge(
|
||||||
|
|
||||||
|
get_meta_from_html($html),
|
||||||
|
|
||||||
|
array(
|
||||||
|
'linkUrl' => $url,
|
||||||
|
'linkText' => $url_params["host"] . $url_params["path"],
|
||||||
|
)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode($result);
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in a new issue