123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- export default {
- install (Vue) {
- //Takes a HTML string then parses it and replaces appropriate
- //links with the relevant expansion
- //Returns a callback with the 'expanded' HTML string
- Vue.prototype.$linkExpander = function (HTML, cb) {
- let parsed = document.createElement('div');
- parsed.innerHTML = HTML;
- let expandPatterns = {
- 'wikipedia': {
- hostnameRegExp: /[a-z]+\.wikipedia\.org/,
- pathnameRegExp: /\/wiki\/.+/,
- getURL (link) {
- let page = link.pathname.split('/').slice(-1)[0];
- let countryVersion = link.hostname.split('.')[0];
-
- return `https://${countryVersion}.wikipedia.org/api/rest_v1/page/summary/${page}?redirect=true`;
- },
- getContent (link, data) {
- let content = data.extract.slice(0, 500).trim();
- return {
- title: data.titles.display,
- URL: data.content_urls.desktop.page,
- content: content.length > 500 ? content + '...' : content
- }
- }
- },
- 'github': {
- hostnameRegExp: /github\.com/,
- pathnameRegExp: /\/.+\/.+/,
- getURL (link) {
- return 'https://api.github.com/repos' + link.pathname;
- },
- getContent (link, data) {
- return {
- title: data.full_name,
- URL: data.html_url,
- content: data.description
- }
- }
- }
- };
- let links = Array
- .from(parsed.querySelectorAll('p a[href]'))
- .filter(a => {
- return (
- a.parentNode.parentNode === parsed &&
- a.parentNode.childNodes.length === 1 &&
- a.innerHTML === a.href
- )
- });
- let expandableLinks = {};
- links.forEach(link => {
- for(let expandName in expandPatterns) {
- let expand = expandPatterns[expandName];
- if(
- expand.hostnameRegExp.test(link.hostname) &&
- expand.pathnameRegExp.test(link.pathname)
- ) {
- if(!expandableLinks[expandName]) {
- expandableLinks[expandName] = [];
- }
- expandableLinks[expandName].push(link);
- break;
- }
- }
- });
- for(let expandName in expandableLinks) {
- let expandPattern = expandPatterns[expandName];
- expandableLinks[expandName].forEach(link => {
- let URL = expandPattern.getURL(link);
- Vue.axios
- .get(URL)
- .then(res => {
- let content = expandPattern.getContent(link, res.data);
- let h = document.createElement.bind(document);
-
- let div = h('div');
- let h2 = h('h2');
- let a = h('a');
- let span = h('span');
- let textNode = document.createTextNode(content.content);
- a.textContent = content.title;
- a.href = content.URL;
- a.setAttribute('target', '_blank');
- a.setAttribute('rel', 'noopener noreferrer');
- span.textContent = 'from ' + link.hostname;
- h2.appendChild(a);
- h2.appendChild(span);
- div.appendChild(h2)
- div.appendChild(textNode)
- div.classList.add('expanded_link');
- link.parentNode.replaceChild(div, link);
- completedAPICall();
- })
- .catch(completedAPICall);
- });
- }
- let completed = 0;
- let completedAPICall = () => {
- completed++;
- if(completed === links.length) {
- cb(parsed.innerHTML);
- }
- }
- }
- }
- }
|