This commit is contained in:
khaydarov 2016-07-02 18:37:10 +03:00
commit 2f2f508659
6 changed files with 231 additions and 52 deletions

View file

@ -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 ) {

View file

@ -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>

View file

@ -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);
}

View file

@ -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;
}
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

95
server/index.php Normal file
View 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);
?>