REFACTOR: Merge onebox and inline onebox code paths

This commit is contained in:
Robin Ward 2017-07-21 13:12:30 -04:00
parent ddc0134b48
commit aa5b8a5749
3 changed files with 59 additions and 104 deletions

View File

@ -4,7 +4,6 @@
//= require ./pretty-text/engines/discourse-markdown/quotes
//= require ./pretty-text/engines/discourse-markdown/emoji
//= require ./pretty-text/engines/discourse-markdown/onebox
//= require ./pretty-text/engines/discourse-markdown/inline-onebox
//= require ./pretty-text/engines/discourse-markdown/bbcode-block
//= require ./pretty-text/engines/discourse-markdown/bbcode-inline
//= require ./pretty-text/engines/discourse-markdown/code

View File

@ -1,68 +0,0 @@
import { cachedInlineOnebox } from 'pretty-text/inline-oneboxer';
function applyInlineOnebox(state, silent) {
if (silent || !state.tokens) {
return;
}
for (let i=1; i<state.tokens.length; i++) {
let token = state.tokens[i];
if (token.type === "inline") {
let children = token.children;
for (let j=0; j<children.length-2; j++) {
let child = children[j];
if (child.type === "link_open" && child.markup === 'linkify' && child.info === 'auto') {
if (j > children.length-3) {
continue;
}
let text = children[j+1];
let close = children[j+2];
// check attrs only include a href
let attrs = child.attrs;
if (!attrs || attrs.length !== 1 || attrs[0][0] !== "href") {
continue;
}
let href = attrs[0][1];
if (!/^http|^\/\//i.test(href)) {
continue;
}
// we already know text matches cause it is an auto link
if (!close || close.type !== "link_close") {
continue;
}
// link must be the same as the href
if (!text || text.content !== href) {
continue;
}
// check for href
let onebox = cachedInlineOnebox(href);
let options = state.md.options.discourse;
if (options.lookupInlineOnebox) {
onebox = options.lookupInlineOnebox(href);
}
if (onebox) {
text.content = onebox.title;
} else if (state.md.options.discourse.previewing) {
attrs.push(["class", "inline-onebox-loading"]);
}
}
}
}
}
}
export function setup(helper) {
helper.registerPlugin(md => {
md.core.ruler.after('onebox', 'inline-onebox', applyInlineOnebox);
});
}

View File

@ -1,53 +1,61 @@
import { lookupCache } from 'pretty-text/oneboxer';
import { cachedInlineOnebox } from 'pretty-text/inline-oneboxer';
const ONEBOX = 1;
const INLINE = 2;
function applyOnebox(state, silent) {
if (silent || !state.tokens || state.tokens.length < 3) {
if (silent || !state.tokens) {
return;
}
let i;
for(i=1;i<state.tokens.length;i++) {
for(let i=1;i<state.tokens.length;i++) {
let token = state.tokens[i];
let prev = state.tokens[i-1];
let prevAccepted = prev.type === "paragraph_open" && prev.level === 0;
let mode = prevAccepted ? ONEBOX : INLINE;
if (token.type === "inline" && prevAccepted) {
let j;
for(j=0;j<token.children.length;j++){
let child = token.children[j];
let children = token.children;
for(let j=0;j<children.length-2;j++){
let child = children[j];
if (child.type === "link_open" && child.markup === 'linkify' && child.info === 'auto') {
if (j === 0 && token.leading_space) {
if (j > children.length-3) {
continue;
}
if (j === 0 && token.leading_space) {
mode = INLINE;
} else if (j > 0) {
let prevSibling = token.children[j-1];
let prevSibling = children[j-1];
if (prevSibling.tag !== 'br' || prevSibling.leading_space) {
continue;
mode = INLINE;
}
}
// look ahead for soft or hard break
let text = token.children[j+1];
let close = token.children[j+2];
let lookahead = token.children[j+3];
let text = children[j+1];
let close = children[j+2];
let lookahead = children[j+3];
if (lookahead && lookahead.tag !== 'br') {
continue;
mode = INLINE;
}
// check attrs only include a href
let attrs = child["attrs"];
let attrs = child.attrs;
if (!attrs || attrs.length !== 1 || attrs[0][0] !== "href") {
continue;
}
let href = attrs[0][1];
// edge case ... what if this is not http or protocoless?
if (!/^http|^\/\//i.test(attrs[0][1])) {
if (!/^http|^\/\//i.test(href)) {
continue;
}
@ -56,28 +64,44 @@ function applyOnebox(state, silent) {
continue;
}
// we already determined earlier that 0 0 was href
let cached = lookupCache(attrs[0][1]);
if (mode === ONEBOX) {
// we already determined earlier that 0 0 was href
let cached = lookupCache(attrs[0][1]);
if (cached) {
// replace link with 2 blank text nodes and inline html for onebox
child.type = 'html_raw';
child.content = cached;
child.inline = true;
if (cached) {
// replace link with 2 blank text nodes and inline html for onebox
child.type = 'html_raw';
child.content = cached;
child.inline = true;
text.type = 'html_raw';
text.content = '';
text.inline = true;
text.type = 'html_raw';
text.content = '';
text.inline = true;
close.type = 'html_raw';
close.content = '';
close.inline = true;
close.type = 'html_raw';
close.content = '';
close.inline = true;
} else {
// decorate...
attrs.push(["class", "onebox"]);
attrs.push(["target", "_blank"]);
} else {
// decorate...
attrs.push(["class", "onebox"]);
attrs.push(["target", "_blank"]);
}
} else if (mode === INLINE) {
let onebox = cachedInlineOnebox(href);
let options = state.md.options.discourse;
if (options.lookupInlineOnebox) {
onebox = options.lookupInlineOnebox(href);
}
if (onebox) {
text.content = onebox.title;
} else if (state.md.options.discourse.previewing) {
attrs.push(["class", "inline-onebox-loading"]);
}
}
}
}
}