editor.js/plugins/link/link.js
George Berezhnoy d2e755086a Destroy module (#157)
* listeners module added

* Destroy method added

* Destroy method for plugins added

* Delete plugins properties from window obj

* Revert "Delete plugins properties from window obj"

This reverts commit 6c91f81229.

* Twitter and instagram api's destroy

* Scripts destoy added

* Fix

* Replace regex with String.indexOf

* Settings for destroyer
2017-02-13 20:54:18 +03:00

351 lines
8.3 KiB
JavaScript

/**
* Created by nostr on 29.06.16.
*/
/**
* Link tool plugin
*/
var link = (function(link_plugin) {
var settings = {
defaultText : 'Вставьте ссылку ...',
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"
}
};
var ui = {
make : function (json) {
var wrapper = ui.wrapper(),
siteImage = ui.image(json.image, settings.elementClasses.image),
siteTitle = ui.title(json.title),
siteDescription = ui.description(json.description),
siteLink = ui.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 = settings.defaultText;
inputTag.contentEditable = false;
return inputTag;
},
wrapper : function () {
var wrapper = document.createElement('div');
wrapper.classList.add('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(settings.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", settings.elementClasses.title);
titleTag.innerHTML = titleText;
return titleTag;
},
description : function (descriptionText) {
var descriptionTag = document.createElement('div');
descriptionTag.classList.add("tool-link-content", settings.elementClasses.description);
descriptionTag.innerHTML = descriptionText;
return descriptionTag;
}
};
var methods = {
blockPasteCallback : function (event) {
var clipboardData = event.clipboardData || window.clipboardData,
pastedData = clipboardData.getData('Text'),
block = event.target.parentNode;
methods.renderLink(pastedData, block);
event.stopPropagation();
},
blockKeyDownCallback : function (event) {
var inputTag = event.target,
block = inputTag.parentNode,
url;
if ( block.classList.contains(settings.elementClasses.error) ) {
block.classList.remove(settings.elementClasses.error);
}
if (event.keyCode == settings.ENTER_KEY) {
url = inputTag.value;
methods.renderLink(url, block);
event.preventDefault();
}
},
renderLink : function (url, block) {
Promise.resolve()
.then(function () {
return methods.urlify(url);
})
.then(function (url) {
/* Show loader gif **/
block.classList.add(settings.elementClasses.loader);
return fetch( link_plugin.config.fetchUrl + '?url=' + encodeURI(url) );
})
.then(function (response) {
if (response.status == "200"){
return response.json();
} else {
return Error("Invalid response status: %o", response);
}
})
.then(function (json) {
methods.composeLinkPreview(json, block);
})
.catch(function(error) {
/* Hide loader gif **/
block.classList.remove(settings.elementClasses.loader);
block.classList.add(settings.elementClasses.error);
codex.editor.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 = ui.make(json);
settings.currentInput.remove();
currentBlock.appendChild(previewBlock);
currentBlock.classList.remove(settings.elementClasses.loader);
}
};
link_plugin.prepare = function (config) {
link_plugin.config = config;
return Promise.resolve();
};
/**
* Make initial header block
* @param {object} JSON with block data
* @return {Element} element to append
*/
link_plugin.makeNewBlock = function (data) {
var wrapper = ui.mainBlock(),
tag = ui.input();
settings.currentInput = tag;
wrapper.appendChild(tag);
wrapper.classList.add('ce-link');
/**
* Bind callbacks
**/
tag.addEventListener('paste', methods.blockPasteCallback, false);
tag.addEventListener('keydown', methods.blockKeyDownCallback, false);
return wrapper;
};
/**
* Method to render HTML block from JSON
*/
link_plugin.render = function (json) {
if ( json ) {
var block = ui.mainBlock(),
tag = ui.make(json);
block.classList.add('ce-link');
block.appendChild(tag);
return block;
} else {
var wrapper = ui.mainBlock(),
tag = ui.input();
settings.currentInput = tag;
wrapper.appendChild(tag);
wrapper.classList.add('ce-link');
/**
* Bind callbacks
**/
tag.addEventListener('paste', methods.blockPasteCallback, false);
tag.addEventListener('keydown', methods.blockKeyDownCallback, false);
return wrapper;
}
};
link_plugin.validate = function (data) {
if (data.url.trim() == '' || data.title.trim() == '' || data.description.trim() == '')
return;
return true;
};
/**
* Method to extract JSON data from HTML block
*/
link_plugin.save = function (blockContent){
var linkElement = settings.elementClasses.link;
var data = {
url : blockContent.querySelector("." + linkElement).href,
shortLink : blockContent.querySelector("." + linkElement).textContent || '',
image : blockContent.querySelector("." + settings.elementClasses.image).src || '',
title : blockContent.querySelector("." + settings.elementClasses.title).textContent || '',
description : blockContent.querySelector("." + settings.elementClasses.description).textContent || ''
};
return data;
};
link_plugin.destroy = function () {
link = null;
};
return link_plugin;
})({});