mirror of
https://github.com/codex-team/editor.js
synced 2024-06-17 13:15:20 +02:00
merged
This commit is contained in:
commit
2f2f508659
|
@ -722,6 +722,13 @@ cEditor.callback = {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* LEFT or UP not at the beginning
|
||||
*/
|
||||
if ( selection.anchorOffset !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Saving caret after keydown event happend */
|
||||
cEditor.caret.save();
|
||||
|
||||
|
@ -732,37 +739,43 @@ cEditor.callback = {
|
|||
}
|
||||
|
||||
/**
|
||||
* Find deepest child node
|
||||
* Iterate child nodes and find First DEEPEST node
|
||||
* We need it to check caret positon (it must be at the begining)
|
||||
* Do nothing if caret is not at the beginning of first child
|
||||
*/
|
||||
focusedNodeHolder = focusedNodeHolder || focusedNode;
|
||||
var caretInFirstChild = false,
|
||||
caretAtTheBeginning = false;
|
||||
|
||||
if (focusedNodeHolder.childNodes.length !== 0) {
|
||||
var editableElement = focusedNode.querySelector('[contenteditable]'),
|
||||
firstChild,
|
||||
deepestTextnode;
|
||||
|
||||
var focusedTextNode = '';
|
||||
|
||||
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 ) {
|
||||
if (!editableElement) {
|
||||
cEditor.core.log('Can not find editable element in current block: %o', 'warn', focusedNode);
|
||||
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);
|
||||
|
||||
nextBlockEditableElement = nextBlock.querySelector('[contenteditable], [contenteditable="true"]');
|
||||
nextBlockEditableElement = nextBlock.querySelector('[contenteditable]');
|
||||
|
||||
console.log("nextBlockEditableElement: %o", nextBlockEditableElement);
|
||||
|
||||
|
@ -1302,6 +1315,9 @@ cEditor.caret = {
|
|||
cEditor.content.workingNodeChanged(block.nextSibling);
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo передалать на prevBlock.querySelector('[contenteditable]') по аналогии с setToNextBlock
|
||||
*/
|
||||
setToPreviousBlock : function(block) {
|
||||
|
||||
if ( !block.previousSibling ) {
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
font-size: 2em;
|
||||
}
|
||||
</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/images/plugin.css" />
|
||||
|
||||
</head>
|
||||
<body style="padding: 100px">
|
||||
|
||||
|
@ -168,7 +170,7 @@
|
|||
link : {
|
||||
'linkUrl' : 'http://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',
|
||||
'description' : 'Поисковик, поисковик, проч.'
|
||||
}
|
||||
|
@ -268,6 +270,6 @@
|
|||
|
||||
</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/images/plugin.js"></script>
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
outline: none;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
font-size: 1em;
|
||||
padding: 12px;
|
||||
transition: background 200ms;
|
||||
}
|
||||
|
||||
.tool-link-panel {
|
||||
|
@ -57,3 +61,23 @@
|
|||
text-decoration: none;
|
||||
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 = {
|
||||
|
||||
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"
|
||||
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('keydown', linkTool.blockKeyDownCallback, false);
|
||||
|
||||
return wrapper;
|
||||
|
||||
},
|
||||
|
@ -82,19 +88,53 @@ var linkTool = {
|
|||
|
||||
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()
|
||||
|
||||
.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) {
|
||||
|
||||
|
@ -105,13 +145,7 @@ var linkTool = {
|
|||
}
|
||||
else {
|
||||
|
||||
return {
|
||||
'linkUrl' : 'http://yandex.ru',
|
||||
'linkText' : 'yandex.ru',
|
||||
'image' : 'https://yastatic.net/morda-logo/i/apple-touch-icon/ru-76x76.png',
|
||||
'title' : 'Яндекс',
|
||||
'description' : 'Сайт, поисковик, проч.'
|
||||
};
|
||||
return Error("Invalid response status: %o", response);
|
||||
|
||||
}
|
||||
|
||||
|
@ -122,6 +156,12 @@ var linkTool = {
|
|||
})
|
||||
|
||||
.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);
|
||||
});
|
||||
|
||||
|
@ -137,7 +177,7 @@ var linkTool = {
|
|||
return links[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
return Promise.reject(Error("Url is not matched"));
|
||||
|
||||
},
|
||||
|
||||
|
@ -155,6 +195,8 @@ var linkTool = {
|
|||
|
||||
currentBlock.appendChild(previewBlock);
|
||||
|
||||
currentBlock.classList.remove(linkTool.elementClasses.loader);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -164,7 +206,7 @@ linkTool.ui = {
|
|||
make : function (json) {
|
||||
|
||||
var wrapper = this.wrapper(),
|
||||
siteImage = this.image(json.image),
|
||||
siteImage = this.image(json.image, linkTool.elementClasses.image),
|
||||
siteTitle = this.title(json.title),
|
||||
siteDescription = this.description(json.description),
|
||||
siteLink = this.link(json.linkUrl, json.linkText);
|
||||
|
@ -190,15 +232,15 @@ linkTool.ui = {
|
|||
|
||||
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');
|
||||
|
||||
imageTag.classList += linkTool.elementClasses.image;
|
||||
imageTag.classList += imageClass;
|
||||
|
||||
imageTag.setAttribute('src', imageSrc);
|
||||
|
||||
|
@ -260,7 +302,7 @@ linkTool.ui = {
|
|||
descriptionTag.innerHTML = descriptionText;
|
||||
|
||||
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