You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-29 22:48:10 +02:00
First pass at linting lib dir
This commit is contained in:
@@ -3,7 +3,6 @@ const htmlUtils = require('lib/htmlUtils');
|
||||
const utils = require('./utils');
|
||||
|
||||
class HtmlToHtml {
|
||||
|
||||
constructor(options) {
|
||||
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
||||
}
|
||||
@@ -31,9 +30,8 @@ class HtmlToHtml {
|
||||
return {
|
||||
html: html,
|
||||
cssFiles: [],
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = HtmlToHtml;
|
||||
module.exports = HtmlToHtml;
|
||||
|
||||
@@ -3,7 +3,6 @@ const HtmlToHtml = require('./HtmlToHtml');
|
||||
const Note = require('lib/models/Note');
|
||||
|
||||
class MarkupToHtml {
|
||||
|
||||
constructor(options) {
|
||||
this.options_ = options;
|
||||
this.renderers_ = {};
|
||||
@@ -33,7 +32,6 @@ class MarkupToHtml {
|
||||
render(markupLanguage, markup, theme, options) {
|
||||
return this.renderer(markupLanguage).render(markup, theme, options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = MarkupToHtml;
|
||||
module.exports = MarkupToHtml;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const { _ } = require('lib/locale');
|
||||
@@ -22,25 +22,24 @@ const hljs = require('highlight.js');
|
||||
const markdownItAnchor = require('markdown-it-anchor');
|
||||
// The keys must match the corresponding entry in Setting.js
|
||||
const plugins = {
|
||||
mark: {module: require('markdown-it-mark')},
|
||||
footnote: {module: require('markdown-it-footnote')},
|
||||
sub: {module: require('markdown-it-sub')},
|
||||
sup: {module: require('markdown-it-sup')},
|
||||
deflist: {module: require('markdown-it-deflist')},
|
||||
abbr: {module: require('markdown-it-abbr')},
|
||||
emoji: {module: require('markdown-it-emoji')},
|
||||
insert: {module: require('markdown-it-ins')},
|
||||
multitable: {module: require('markdown-it-multimd-table'), options: { enableMultilineRows: true, enableRowspan: true }},
|
||||
toc: {module: require('markdown-it-toc-done-right'), options: { listType: 'ul' }},
|
||||
mark: { module: require('markdown-it-mark') },
|
||||
footnote: { module: require('markdown-it-footnote') },
|
||||
sub: { module: require('markdown-it-sub') },
|
||||
sup: { module: require('markdown-it-sup') },
|
||||
deflist: { module: require('markdown-it-deflist') },
|
||||
abbr: { module: require('markdown-it-abbr') },
|
||||
emoji: { module: require('markdown-it-emoji') },
|
||||
insert: { module: require('markdown-it-ins') },
|
||||
multitable: { module: require('markdown-it-multimd-table'), options: { enableMultilineRows: true, enableRowspan: true } },
|
||||
toc: { module: require('markdown-it-toc-done-right'), options: { listType: 'ul' } },
|
||||
};
|
||||
|
||||
class MdToHtml {
|
||||
|
||||
constructor(options = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
// Must include last "/"
|
||||
this.resourceBaseUrl_ = ('resourceBaseUrl' in options) ? options.resourceBaseUrl : null;
|
||||
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
||||
|
||||
this.cachedOutputs_ = {};
|
||||
|
||||
@@ -106,7 +105,7 @@ class MdToHtml {
|
||||
} catch (error) {
|
||||
return '<pre class="hljs"><code>' + markdownIt.utils.escapeHtml(str) + '</code></pre>';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const ruleOptions = Object.assign({}, options, { resourceBaseUrl: this.resourceBaseUrl_ });
|
||||
@@ -118,7 +117,7 @@ class MdToHtml {
|
||||
// const someMarkdownPlugin = require('someMarkdownPlugin');
|
||||
// markdownIt.use(someMarkdownPlugin);
|
||||
//
|
||||
// 2. If the plugin does not need any application specific data, and you want the user
|
||||
// 2. If the plugin does not need any application specific data, and you want the user
|
||||
// to be able to toggle the plugin:
|
||||
//
|
||||
// Add the plugin to the plugins object
|
||||
@@ -146,7 +145,7 @@ class MdToHtml {
|
||||
if (Setting.value('markdown.plugin.katex')) markdownIt.use(rules.katex(context, ruleOptions));
|
||||
markdownIt.use(rules.highlight_keywords(context, ruleOptions));
|
||||
markdownIt.use(rules.code_inline(context, ruleOptions));
|
||||
markdownIt.use(markdownItAnchor)
|
||||
markdownIt.use(markdownItAnchor);
|
||||
|
||||
for (let key in plugins) {
|
||||
if (Setting.value('markdown.plugin.' + key)) markdownIt.use(plugins[key].module, plugins[key].options);
|
||||
@@ -191,7 +190,6 @@ class MdToHtml {
|
||||
injectedJavaScript() {
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = MdToHtml;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const utils = require('../../utils');
|
||||
|
||||
@@ -44,20 +44,12 @@ function createPrefixTokens(Token, id, checked, label, postMessageSyntax, source
|
||||
`;
|
||||
|
||||
token = new Token('checkbox_input', 'input', 0);
|
||||
token.attrs = [
|
||||
['type', 'checkbox'],
|
||||
['id', id],
|
||||
['onclick', js],
|
||||
];
|
||||
token.attrs = [['type', 'checkbox'], ['id', id], ['onclick', js]];
|
||||
if (checked) token.attrs.push(['checked', 'true']);
|
||||
tokens.push(token);
|
||||
|
||||
token = new Token('label_open', 'label', 1);
|
||||
token.attrs = [
|
||||
['id', labelId],
|
||||
['for', id],
|
||||
['class', 'checkbox-label-' + checkedString],
|
||||
];
|
||||
token.attrs = [['id', labelId], ['for', id], ['class', 'checkbox-label-' + checkedString]];
|
||||
tokens.push(token);
|
||||
|
||||
if (label) {
|
||||
@@ -78,7 +70,7 @@ function installRule(markdownIt, mdOptions, ruleOptions, context) {
|
||||
const tokens = state.tokens;
|
||||
const Token = state.Token;
|
||||
|
||||
const checkboxPattern = /^\[([x|X| ])\] (.*)$/
|
||||
const checkboxPattern = /^\[([x|X| ])\] (.*)$/;
|
||||
let currentListItem = null;
|
||||
let processedFirstInline = false;
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
@@ -135,4 +127,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions, context);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const defaultRender = markdownIt.renderer.rules.code_inline || function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
const defaultRender =
|
||||
markdownIt.renderer.rules.code_inline ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
markdownIt.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
|
||||
const token = tokens[idx];
|
||||
@@ -17,4 +19,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const utils = require('../../utils');
|
||||
const StringUtils = require('lib/string-utils.js');
|
||||
@@ -56,7 +56,7 @@ function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const splitted = StringUtils.surroundKeywords(keywords, child.content, divider, divider).split(divider);
|
||||
const splittedTokens = createHighlightedTokens(Token, splitted);
|
||||
if (splittedTokens.length <= 1) continue;
|
||||
|
||||
|
||||
token.children = markdownIt.utils.arrayReplaceAt(token.children, j, splittedTokens);
|
||||
j += splittedTokens.length - 1;
|
||||
}
|
||||
@@ -68,4 +68,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const htmlUtils = require('lib/htmlUtils.js');
|
||||
const utils = require('../../utils');
|
||||
@@ -12,15 +12,19 @@ function renderImageHtml(before, src, after, ruleOptions) {
|
||||
}
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const htmlBlockDefaultRender = markdownIt.renderer.rules.html_block || function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
const htmlBlockDefaultRender =
|
||||
markdownIt.renderer.rules.html_block ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
const htmlInlineDefaultRender = markdownIt.renderer.rules.html_inline || function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
const htmlInlineDefaultRender =
|
||||
markdownIt.renderer.rules.html_inline ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
const imageRegex = /<img(.*?)src=["'](.*?)["'](.*?)>/gi
|
||||
const imageRegex = /<img(.*?)src=["'](.*?)["'](.*?)>/gi;
|
||||
|
||||
const handleImageTags = function(defaultRender) {
|
||||
return function(tokens, idx, options, env, self) {
|
||||
@@ -33,8 +37,8 @@ function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
if (!Resource.isResourceUrl(src)) return defaultRender(tokens, idx, options, env, self);
|
||||
return renderImageHtml(before, src, after, ruleOptions);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// It seems images sometimes are inline, sometimes a block
|
||||
// to make sure they both render correctly.
|
||||
@@ -46,4 +50,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const utils = require('../../utils');
|
||||
const htmlUtils = require('lib/htmlUtils.js');
|
||||
@@ -26,4 +26,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ const katexCss = require('lib/csstojs/katex.css.js');
|
||||
const md5 = require('md5');
|
||||
|
||||
// const style = `
|
||||
// /*
|
||||
// /*
|
||||
// This is to fix https://github.com/laurent22/joplin/issues/764
|
||||
// Without this, the tag attached to an equation float at an absolute position of the page,
|
||||
// instead of a position relative to the container.
|
||||
@@ -26,7 +26,8 @@ const md5 = require('md5');
|
||||
// Test if potential opening or closing delimieter
|
||||
// Assumes that there is a "$" at state.src[pos]
|
||||
function isValidDelim(state, pos) {
|
||||
var prevChar, nextChar,
|
||||
var prevChar,
|
||||
nextChar,
|
||||
max = state.posMax,
|
||||
can_open = true,
|
||||
can_close = true;
|
||||
@@ -36,28 +37,31 @@ function isValidDelim(state, pos) {
|
||||
|
||||
// Check non-whitespace conditions for opening and closing, and
|
||||
// check that closing delimeter isn't followed by a number
|
||||
if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ ||
|
||||
(nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) {
|
||||
if (prevChar === 0x20 /* " " */ || prevChar === 0x09 /* \t */ || (nextChar >= 0x30 /* "0" */ && nextChar <= 0x39) /* "9" */) {
|
||||
can_close = false;
|
||||
}
|
||||
if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) {
|
||||
if (nextChar === 0x20 /* " " */ || nextChar === 0x09 /* \t */) {
|
||||
can_open = false;
|
||||
}
|
||||
|
||||
return {
|
||||
can_open: can_open,
|
||||
can_close: can_close
|
||||
can_close: can_close,
|
||||
};
|
||||
}
|
||||
|
||||
function math_inline(state, silent) {
|
||||
var start, match, token, res, pos, esc_count;
|
||||
|
||||
if (state.src[state.pos] !== "$") { return false; }
|
||||
if (state.src[state.pos] !== '$') {
|
||||
return false;
|
||||
}
|
||||
|
||||
res = isValidDelim(state, state.pos);
|
||||
if (!res.can_open) {
|
||||
if (!silent) { state.pending += "$"; }
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos += 1;
|
||||
return true;
|
||||
}
|
||||
@@ -68,27 +72,35 @@ function math_inline(state, silent) {
|
||||
// we have found an opening delimieter already.
|
||||
start = state.pos + 1;
|
||||
match = start;
|
||||
while ( (match = state.src.indexOf("$", match)) !== -1) {
|
||||
while ((match = state.src.indexOf('$', match)) !== -1) {
|
||||
// Found potential $, look for escapes, pos will point to
|
||||
// first non escape when complete
|
||||
pos = match - 1;
|
||||
while (state.src[pos] === "\\") { pos -= 1; }
|
||||
while (state.src[pos] === '\\') {
|
||||
pos -= 1;
|
||||
}
|
||||
|
||||
// Even number of escapes, potential closing delimiter found
|
||||
if ( ((match - pos) % 2) == 1 ) { break; }
|
||||
if ((match - pos) % 2 == 1) {
|
||||
break;
|
||||
}
|
||||
match += 1;
|
||||
}
|
||||
|
||||
// No closing delimter found. Consume $ and continue.
|
||||
if (match === -1) {
|
||||
if (!silent) { state.pending += "$"; }
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos = start;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we have empty content, ie: $$. Do not parse.
|
||||
if (match - start === 0) {
|
||||
if (!silent) { state.pending += "$$"; }
|
||||
if (!silent) {
|
||||
state.pending += '$$';
|
||||
}
|
||||
state.pos = start + 1;
|
||||
return true;
|
||||
}
|
||||
@@ -96,14 +108,16 @@ function math_inline(state, silent) {
|
||||
// Check for valid closing delimiter
|
||||
res = isValidDelim(state, match);
|
||||
if (!res.can_close) {
|
||||
if (!silent) { state.pending += "$"; }
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos = start;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
token = state.push('math_inline', 'math', 0);
|
||||
token.markup = "$";
|
||||
token = state.push('math_inline', 'math', 0);
|
||||
token.markup = '$';
|
||||
token.content = state.src.slice(start, match);
|
||||
}
|
||||
|
||||
@@ -111,54 +125,68 @@ function math_inline(state, silent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function math_block(state, start, end, silent){
|
||||
var firstLine, lastLine, next, lastPos, found = false, token,
|
||||
function math_block(state, start, end, silent) {
|
||||
var firstLine,
|
||||
lastLine,
|
||||
next,
|
||||
lastPos,
|
||||
found = false,
|
||||
token,
|
||||
pos = state.bMarks[start] + state.tShift[start],
|
||||
max = state.eMarks[start]
|
||||
max = state.eMarks[start];
|
||||
|
||||
if(pos + 2 > max){ return false; }
|
||||
if(state.src.slice(pos,pos+2)!=='$$'){ return false; }
|
||||
if (pos + 2 > max) {
|
||||
return false;
|
||||
}
|
||||
if (state.src.slice(pos, pos + 2) !== '$$') {
|
||||
return false;
|
||||
}
|
||||
|
||||
pos += 2;
|
||||
firstLine = state.src.slice(pos,max);
|
||||
firstLine = state.src.slice(pos, max);
|
||||
|
||||
if(silent){ return true; }
|
||||
if(firstLine.trim().slice(-2)==='$$'){
|
||||
if (silent) {
|
||||
return true;
|
||||
}
|
||||
if (firstLine.trim().slice(-2) === '$$') {
|
||||
// Single line expression
|
||||
firstLine = firstLine.trim().slice(0, -2);
|
||||
found = true;
|
||||
}
|
||||
|
||||
for(next = start; !found; ){
|
||||
|
||||
for (next = start; !found; ) {
|
||||
next++;
|
||||
|
||||
if(next >= end){ break; }
|
||||
if (next >= end) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos = state.bMarks[next]+state.tShift[next];
|
||||
pos = state.bMarks[next] + state.tShift[next];
|
||||
max = state.eMarks[next];
|
||||
|
||||
if(pos < max && state.tShift[next] < state.blkIndent){
|
||||
if (pos < max && state.tShift[next] < state.blkIndent) {
|
||||
// non-empty line with negative indent should stop the list:
|
||||
break;
|
||||
}
|
||||
|
||||
if(state.src.slice(pos,max).trim().slice(-2)==='$$'){
|
||||
lastPos = state.src.slice(0,max).lastIndexOf('$$');
|
||||
lastLine = state.src.slice(pos,lastPos);
|
||||
if (
|
||||
state.src
|
||||
.slice(pos, max)
|
||||
.trim()
|
||||
.slice(-2) === '$$'
|
||||
) {
|
||||
lastPos = state.src.slice(0, max).lastIndexOf('$$');
|
||||
lastLine = state.src.slice(pos, lastPos);
|
||||
found = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.line = next + 1;
|
||||
|
||||
token = state.push('math_block', 'math', 0);
|
||||
token.block = true;
|
||||
token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '')
|
||||
+ state.getLines(start + 1, next, state.tShift[start], true)
|
||||
+ (lastLine && lastLine.trim() ? lastLine : '');
|
||||
token.map = [ start, state.line ];
|
||||
token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : '');
|
||||
token.map = [start, state.line];
|
||||
token.markup = '$$';
|
||||
return true;
|
||||
}
|
||||
@@ -170,7 +198,7 @@ module.exports = function(context, ruleOptions) {
|
||||
// Keep macros that persist across Katex blocks to allow defining a macro
|
||||
// in one block and re-using it later in other blocks.
|
||||
// https://github.com/laurent22/joplin/issues/1105
|
||||
context.__katex = { macros: {} };
|
||||
context.__katex = { macros: {} };
|
||||
|
||||
const addContextAssets = () => {
|
||||
context.css['katex'] = katexCss;
|
||||
@@ -186,7 +214,7 @@ module.exports = function(context, ruleOptions) {
|
||||
// Fonts must go under the resourceDir directory because this is the baseUrl of NoteBodyViewer
|
||||
const baseDir = Setting.value('resourceDir');
|
||||
await shim.fsDriver().mkdir(baseDir + '/fonts');
|
||||
|
||||
|
||||
await shim.fetchBlob('https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0-beta1/fonts/KaTeX_Main-Regular.woff2', { overwrite: false, path: baseDir + '/fonts/KaTeX_Main-Regular.woff2' });
|
||||
await shim.fetchBlob('https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0-beta1/fonts/KaTeX_Math-Italic.woff2', { overwrite: false, path: baseDir + '/fonts/KaTeX_Math-Italic.woff2' });
|
||||
await shim.fetchBlob('https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0-beta1/fonts/KaTeX_Size1-Regular.woff2', { overwrite: false, path: baseDir + '/fonts/KaTeX_Size1-Regular.woff2' });
|
||||
@@ -194,7 +222,7 @@ module.exports = function(context, ruleOptions) {
|
||||
|
||||
assetsLoaded_ = true;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function renderToStringWithCache(latex, options) {
|
||||
const cacheKey = md5(escape(latex) + escape(JSON.stringify(options)));
|
||||
@@ -219,41 +247,45 @@ module.exports = function(context, ruleOptions) {
|
||||
options.macros = context.__katex.macros;
|
||||
|
||||
// set KaTeX as the renderer for markdown-it-simplemath
|
||||
var katexInline = function(latex){
|
||||
var katexInline = function(latex) {
|
||||
options.displayMode = false;
|
||||
try{
|
||||
try {
|
||||
return renderToStringWithCache(latex, options);
|
||||
} catch(error){
|
||||
if(options.throwOnError){ console.log(error); }
|
||||
} catch (error) {
|
||||
if (options.throwOnError) {
|
||||
console.log(error);
|
||||
}
|
||||
return latex;
|
||||
}
|
||||
};
|
||||
|
||||
var inlineRenderer = function(tokens, idx){
|
||||
var inlineRenderer = function(tokens, idx) {
|
||||
addContextAssets();
|
||||
return katexInline(tokens[idx].content);
|
||||
};
|
||||
|
||||
var katexBlock = function(latex){
|
||||
var katexBlock = function(latex) {
|
||||
options.displayMode = true;
|
||||
try{
|
||||
return "<p>" + renderToStringWithCache(latex, options) + "</p>";
|
||||
} catch(error){
|
||||
if(options.throwOnError){ console.log(error); }
|
||||
try {
|
||||
return '<p>' + renderToStringWithCache(latex, options) + '</p>';
|
||||
} catch (error) {
|
||||
if (options.throwOnError) {
|
||||
console.log(error);
|
||||
}
|
||||
return latex;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var blockRenderer = function(tokens, idx){
|
||||
var blockRenderer = function(tokens, idx) {
|
||||
addContextAssets();
|
||||
return katexBlock(tokens[idx].content) + '\n';
|
||||
}
|
||||
};
|
||||
|
||||
md.inline.ruler.after('escape', 'math_inline', math_inline);
|
||||
md.block.ruler.after('blockquote', 'math_block', math_block, {
|
||||
alt: [ 'paragraph', 'reference', 'blockquote', 'list' ]
|
||||
alt: ['paragraph', 'reference', 'blockquote', 'list'],
|
||||
});
|
||||
md.renderer.rules.math_inline = inlineRenderer;
|
||||
md.renderer.rules.math_block = blockRenderer;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const utils = require('../../utils');
|
||||
|
||||
const loaderImage = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="16px" height="16px" viewBox="0 0 128 128" xml:space="preserve"><g><circle cx="16" cy="64" r="16" fill="#000000" fill-opacity="1"/><circle cx="16" cy="64" r="16" fill="#555555" fill-opacity="0.67" transform="rotate(45,64,64)"/><circle cx="16" cy="64" r="16" fill="#949494" fill-opacity="0.42" transform="rotate(90,64,64)"/><circle cx="16" cy="64" r="16" fill="#cccccc" fill-opacity="0.2" transform="rotate(135,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(180,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(225,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(270,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(315,64,64)"/><animateTransform attributeName="transform" type="rotate" values="0 64 64;315 64 64;270 64 64;225 64 64;180 64 64;135 64 64;90 64 64;45 64 64" calcMode="discrete" dur="720ms" repeatCount="indefinite"></animateTransform></g></svg>';
|
||||
const loaderImage =
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="16px" height="16px" viewBox="0 0 128 128" xml:space="preserve"><g><circle cx="16" cy="64" r="16" fill="#000000" fill-opacity="1"/><circle cx="16" cy="64" r="16" fill="#555555" fill-opacity="0.67" transform="rotate(45,64,64)"/><circle cx="16" cy="64" r="16" fill="#949494" fill-opacity="0.42" transform="rotate(90,64,64)"/><circle cx="16" cy="64" r="16" fill="#cccccc" fill-opacity="0.2" transform="rotate(135,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(180,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(225,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(270,64,64)"/><circle cx="16" cy="64" r="16" fill="#e1e1e1" fill-opacity="0.12" transform="rotate(315,64,64)"/><animateTransform attributeName="transform" type="rotate" values="0 64 64;315 64 64;270 64 64;225 64 64;180 64 64;135 64 64;90 64 64;45 64 64" calcMode="discrete" dur="720ms" repeatCount="indefinite"></animateTransform></g></svg>';
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) {
|
||||
markdownIt.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
||||
const token = tokens[idx];
|
||||
let href = utils.getAttr(token.attrs, 'href');
|
||||
const text = utils.getAttr(token.attrs, 'text');
|
||||
const isResourceUrl = Resource.isResourceUrl(href);
|
||||
const title = isResourceUrl ? utils.getAttr(token.attrs, 'title') : href;
|
||||
|
||||
let resourceIdAttr = "";
|
||||
let icon = "";
|
||||
|
||||
let resourceIdAttr = '';
|
||||
let icon = '';
|
||||
let hrefAttr = '#';
|
||||
if (isResourceUrl) {
|
||||
const resourceId = Resource.pathToId(href);
|
||||
@@ -27,19 +28,19 @@ function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const icon = utils.resourceStatusFile(resourceStatus);
|
||||
return '<a class="not-loaded-resource resource-status-' + resourceStatus + '" data-resource-id="' + resourceId + '">' + '<img src="data:image/svg+xml;utf8,' + htmlentities(icon) + '"/>';
|
||||
} else {
|
||||
href = "joplin://" + resourceId;
|
||||
href = 'joplin://' + resourceId;
|
||||
resourceIdAttr = "data-resource-id='" + resourceId + "'";
|
||||
icon = '<span class="resource-icon"></span>';
|
||||
}
|
||||
} else {
|
||||
// If the link is a plain URL (as opposed to a resource link), set the href to the actual
|
||||
// link. This allows the link to be exported too when exporting to PDF.
|
||||
// link. This allows the link to be exported too when exporting to PDF.
|
||||
hrefAttr = href;
|
||||
}
|
||||
|
||||
let js = ruleOptions.postMessageSyntax + "(" + JSON.stringify(href) + "); return false;";
|
||||
let js = ruleOptions.postMessageSyntax + '(' + JSON.stringify(href) + '); return false;';
|
||||
if (hrefAttr.indexOf('#') === 0 && href.indexOf('#') === 0) js = ''; // If it's an internal anchor, don't add any JS since the webview is going to handle navigating to the right place
|
||||
return "<a data-from-md " + resourceIdAttr + " title='" + htmlentities(title) + "' href='" + hrefAttr + "' onclick='" + js + "'>" + icon;
|
||||
return '<a data-from-md ' + resourceIdAttr + " title='" + htmlentities(title) + "' href='" + hrefAttr + "' onclick='" + js + "'>" + icon;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,4 +48,4 @@ module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,28 +2,28 @@ module.exports = function(markdownIt) {
|
||||
// Add `file:` protocol in linkify to allow text in the format of "file://..." to translate into
|
||||
// file-URL links in html view
|
||||
markdownIt.linkify.add('file:', {
|
||||
validate: function (text, pos, self) {
|
||||
var tail = text.slice(pos);
|
||||
if (!self.re.file) {
|
||||
// matches all local file URI on Win/Unix/MacOS systems including reserved characters in some OS (i.e. no OS specific sanity check)
|
||||
self.re.file = new RegExp('^[\\/]{2,3}[\\S]+');
|
||||
}
|
||||
if (self.re.file.test(tail)) {
|
||||
validate: function(text, pos, self) {
|
||||
var tail = text.slice(pos);
|
||||
if (!self.re.file) {
|
||||
// matches all local file URI on Win/Unix/MacOS systems including reserved characters in some OS (i.e. no OS specific sanity check)
|
||||
self.re.file = new RegExp('^[\\/]{2,3}[\\S]+');
|
||||
}
|
||||
if (self.re.file.test(tail)) {
|
||||
return tail.match(self.re.file)[0].length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
});
|
||||
|
||||
// enable file link URLs in MarkdownIt. Keeps other URL restrictions of MarkdownIt untouched.
|
||||
// Format [link name](file://...)
|
||||
markdownIt.validateLink = function (url) {
|
||||
// Format [link name](file://...)
|
||||
markdownIt.validateLink = function(url) {
|
||||
var BAD_PROTO_RE = /^(vbscript|javascript|data):/;
|
||||
var GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/;
|
||||
|
||||
// url should be normalized at this point, and existing entities are decoded
|
||||
// url should be normalized at this point, and existing entities are decoded
|
||||
var str = url.trim().toLowerCase();
|
||||
|
||||
return BAD_PROTO_RE.test(str) ? (GOOD_DATA_RE.test(str) ? true : false) : true;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,17 +10,32 @@ module.exports = function(style, options) {
|
||||
const fontFamily = "'Avenir', 'Arial', sans-serif";
|
||||
const listMarginLeft = '1.7em';
|
||||
|
||||
const css = `
|
||||
const css =
|
||||
`
|
||||
body {
|
||||
font-size: ` + style.htmlFontSize + `;
|
||||
color: ` + style.htmlColor + `;
|
||||
line-height: ` + style.htmlLineHeight + `;
|
||||
background-color: ` + style.htmlBackgroundColor + `;
|
||||
font-family: ` + fontFamily + `;
|
||||
padding-bottom: ` + options.paddingBottom + `;
|
||||
font-size: ` +
|
||||
style.htmlFontSize +
|
||||
`;
|
||||
color: ` +
|
||||
style.htmlColor +
|
||||
`;
|
||||
line-height: ` +
|
||||
style.htmlLineHeight +
|
||||
`;
|
||||
background-color: ` +
|
||||
style.htmlBackgroundColor +
|
||||
`;
|
||||
font-family: ` +
|
||||
fontFamily +
|
||||
`;
|
||||
padding-bottom: ` +
|
||||
options.paddingBottom +
|
||||
`;
|
||||
}
|
||||
strong {
|
||||
color: ` + style.colorBright + `
|
||||
color: ` +
|
||||
style.colorBright +
|
||||
`
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
@@ -68,7 +83,9 @@ module.exports = function(style, options) {
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid ` + style.htmlDividerColor + `;
|
||||
border-bottom: 1px solid ` +
|
||||
style.htmlDividerColor +
|
||||
`;
|
||||
padding-bottom: .3em;
|
||||
}
|
||||
h2 {
|
||||
@@ -84,7 +101,9 @@ module.exports = function(style, options) {
|
||||
font-weight: bold;
|
||||
}
|
||||
a {
|
||||
color: ` + style.htmlLinkColor + `;
|
||||
color: ` +
|
||||
style.htmlLinkColor +
|
||||
`;
|
||||
}
|
||||
ul, ol {
|
||||
padding-left: 0;
|
||||
@@ -105,12 +124,16 @@ module.exports = function(style, options) {
|
||||
width: 1.15em;
|
||||
height: 1.45em;
|
||||
margin-right: 0.4em;
|
||||
background-color: ` + style.htmlColor + `;
|
||||
background-color: ` +
|
||||
style.htmlColor +
|
||||
`;
|
||||
/* Awesome Font file */
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1892' xmlns='http://www.w3.org/2000/svg'><path d='M288 128C129 128 0 257 0 416v960c0 159 129 288 288 288h960c159 0 288-129 288-288V416c0-159-129-288-288-288H288zm449.168 236.572l263.434.565 263.431.562.584 73.412.584 73.412-42.732 1.504c-23.708.835-47.002 2.774-52.322 4.36-14.497 4.318-23.722 12.902-29.563 27.51l-5.12 12.802-1.403 291.717c-1.425 295.661-1.626 302.586-9.936 343.043-15.2 74-69.604 150.014-142.197 198.685-58.287 39.08-121.487 60.47-208.155 70.45-22.999 2.648-122.228 2.636-141.976-.024l-.002.006c-69.785-9.377-108.469-20.202-154.848-43.332-85.682-42.73-151.778-116.991-177.537-199.469-10.247-32.81-11.407-40.853-11.375-78.754.026-31.257.76-39.15 5.024-54.043 8.94-31.228 20.912-51.733 43.56-74.62 27.312-27.6 55.812-40.022 95.524-41.633 37.997-1.542 63.274 5.024 87.23 22.66 15.263 11.235 30.828 33.238 39.537 55.884 5.52 14.355 5.949 18.31 7.549 69.569 1.675 53.648 3.05 63.99 11.674 87.785 11.777 32.499 31.771 55.017 61.46 69.22 26.835 12.838 47.272 16.785 80.56 15.56 21.646-.798 30.212-2.135 43.208-6.741 38.682-13.708 70.96-44.553 86.471-82.635 16.027-39.348 15.995-38.647 15.947-361.595-.042-283.26-.09-286.272-4.568-296.153-10.958-24.171-22.488-28.492-81.074-30.377l-42.969-1.38v-147.95z'/></svg>");
|
||||
}
|
||||
blockquote {
|
||||
border-left: 4px solid ` + style.htmlCodeBorderColor + `;
|
||||
border-left: 4px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
padding-left: 1.2em;
|
||||
margin-left: 0;
|
||||
opacity: .7;
|
||||
@@ -118,45 +141,77 @@ module.exports = function(style, options) {
|
||||
table {
|
||||
text-align: left-align;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid ` + style.htmlCodeBorderColor + `;
|
||||
background-color: ` + style.htmlBackgroundColor + `;
|
||||
border: 1px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
background-color: ` +
|
||||
style.htmlBackgroundColor +
|
||||
`;
|
||||
}
|
||||
td, th {
|
||||
padding: .5em 1em .5em 1em;
|
||||
font-size: ` + style.htmlFontSize + `;
|
||||
color: ` + style.htmlColor + `;
|
||||
font-family: ` + fontFamily + `;
|
||||
font-size: ` +
|
||||
style.htmlFontSize +
|
||||
`;
|
||||
color: ` +
|
||||
style.htmlColor +
|
||||
`;
|
||||
font-family: ` +
|
||||
fontFamily +
|
||||
`;
|
||||
}
|
||||
td {
|
||||
border: 1px solid ` + style.htmlCodeBorderColor + `;
|
||||
border: 1px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
}
|
||||
th {
|
||||
border: 1px solid ` + style.htmlCodeBorderColor + `;
|
||||
border-bottom: 2px solid ` + style.htmlCodeBorderColor + `;
|
||||
background-color: ` + style.htmlTableBackgroundColor + `;
|
||||
border: 1px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
border-bottom: 2px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
background-color: ` +
|
||||
style.htmlTableBackgroundColor +
|
||||
`;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: ` + style.htmlTableBackgroundColor + `;
|
||||
background-color: ` +
|
||||
style.htmlTableBackgroundColor +
|
||||
`;
|
||||
}
|
||||
tr:hover {
|
||||
background-color: ` + style.raisedBackgroundColor + `;
|
||||
background-color: ` +
|
||||
style.raisedBackgroundColor +
|
||||
`;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 2px solid ` + style.htmlDividerColor + `;
|
||||
border-bottom: 2px solid ` +
|
||||
style.htmlDividerColor +
|
||||
`;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.inline-code {
|
||||
border: 1px solid ` + style.htmlCodeBorderColor + `;
|
||||
background-color: ` + style.htmlCodeBackgroundColor + `;
|
||||
border: 1px solid ` +
|
||||
style.htmlCodeBorderColor +
|
||||
`;
|
||||
background-color: ` +
|
||||
style.htmlCodeBackgroundColor +
|
||||
`;
|
||||
padding-right: .2em;
|
||||
padding-left: .2em;
|
||||
border-radius: .25em;
|
||||
color: ` + style.htmlCodeColor + `;
|
||||
font-size: ` + style.htmlCodeFontSize + `;
|
||||
color: ` +
|
||||
style.htmlCodeColor +
|
||||
`;
|
||||
font-size: ` +
|
||||
style.htmlCodeFontSize +
|
||||
`;
|
||||
}
|
||||
|
||||
.highlighted-keyword {
|
||||
@@ -203,4 +258,4 @@ module.exports = function(style, options) {
|
||||
`;
|
||||
|
||||
return [normalizeCss, css];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = (new Entities()).encode;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
const utils = {};
|
||||
|
||||
@@ -9,7 +9,7 @@ utils.getAttr = function(attrs, name, defaultValue = null) {
|
||||
if (attrs[i][0] === name) return attrs[i].length > 1 ? attrs[i][1] : null;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
utils.notDownloadedResource = function() {
|
||||
return `
|
||||
@@ -17,7 +17,7 @@ utils.notDownloadedResource = function() {
|
||||
<path d="M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
utils.notDownloadedImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/file-image-o.svg
|
||||
@@ -27,7 +27,7 @@ utils.notDownloadedImage = function() {
|
||||
<path d="M640 576c0 106-86 192-192 192s-192-86-192-192 86-192 192-192 192 86 192 192zm1024 384v448H256v-192l320-320 160 160 512-512zm96-704H160c-17 0-32 15-32 32v1216c0 17 15 32 32 32h1600c17 0 32-15 32-32V288c0-17-15-32-32-32zm160 32v1216c0 88-72 160-160 160H160c-88 0-160-72-160-160V288c0-88 72-160 160-160h1600c88 0 160 72 160 160z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
utils.notDownloadedFile = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/file-o.svg
|
||||
@@ -36,7 +36,7 @@ utils.notDownloadedFile = function() {
|
||||
<path d="M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
utils.errorImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/times-circle.svg
|
||||
@@ -45,7 +45,7 @@ utils.errorImage = function() {
|
||||
<path d="M1149 1122c0-17-7-33-19-45L949 896l181-181c12-12 19-28 19-45s-7-34-19-46l-90-90c-12-12-29-19-46-19s-33 7-45 19L768 715 587 534c-12-12-28-19-45-19s-34 7-46 19l-90 90c-12 12-19 29-19 46s7 33 19 45l181 181-181 181c-12 12-19 28-19 45s7 34 19 46l90 90c12 12 29 19 46 19s33-7 45-19l181-181 181 181c12 12 28 19 45 19s34-7 46-19l90-90c12-12 19-29 19-46zm387-226c0 424-344 768-768 768S0 1320 0 896s344-768 768-768 768 344 768 768z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
utils.loaderImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/hourglass-half.svg
|
||||
@@ -54,12 +54,12 @@ utils.loaderImage = function() {
|
||||
<path d="M1408 128c0 370-177 638-373 768 196 130 373 398 373 768h96c18 0 32 14 32 32v64c0 18-14 32-32 32H32c-18 0-32-14-32-32v-64c0-18 14-32 32-32h96c0-370 177-638 373-768-196-130-373-398-373-768H32c-18 0-32-14-32-32V32C0 14 14 0 32 0h1472c18 0 32 14 32 32v64c0 18-14 32-32 32h-96zm-128 0H256c0 146 33 275 85 384h854c52-109 85-238 85-384zm-57 1216c-74-193-207-330-340-384H653c-133 54-266 191-340 384h910z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
utils.resourceStatusImage = function(state) {
|
||||
if (state === 'notDownloaded') return utils.notDownloadedResource();
|
||||
return utils.resourceStatusFile(state);
|
||||
}
|
||||
};
|
||||
|
||||
utils.resourceStatusFile = function(state) {
|
||||
if (state === 'notDownloaded') return utils.notDownloadedResource();
|
||||
@@ -68,7 +68,7 @@ utils.resourceStatusFile = function(state) {
|
||||
if (state === 'error') return utils.errorImage();
|
||||
|
||||
throw new Error('Unknown state: ' + state);
|
||||
}
|
||||
};
|
||||
|
||||
utils.resourceStatus = function(resourceInfo) {
|
||||
let resourceStatus = 'ready';
|
||||
@@ -91,11 +91,11 @@ utils.resourceStatus = function(resourceInfo) {
|
||||
}
|
||||
|
||||
return resourceStatus;
|
||||
}
|
||||
};
|
||||
|
||||
utils.imageReplacement = function(src, resources, resourceBaseUrl) {
|
||||
if (!Resource.isResourceUrl(src)) return null;
|
||||
|
||||
|
||||
const resourceId = Resource.urlToId(src);
|
||||
const result = resources[resourceId];
|
||||
const resource = result ? result.item : null;
|
||||
@@ -112,11 +112,11 @@ utils.imageReplacement = function(src, resources, resourceBaseUrl) {
|
||||
if (resourceBaseUrl) newSrc = resourceBaseUrl + newSrc;
|
||||
return {
|
||||
'data-resource-id': resource.id,
|
||||
'src': newSrc,
|
||||
src: newSrc,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = utils;
|
||||
module.exports = utils;
|
||||
|
||||
@@ -5,7 +5,7 @@ let manualDownloadResourceElements = [];
|
||||
webviewLib.onUnloadedResourceClick = function(event) {
|
||||
const resourceId = event.currentTarget.getAttribute('data-resource-id');
|
||||
webviewLib.options_.postMessage('markForDownload:' + resourceId);
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.setupResourceManualDownload = function() {
|
||||
for (const element of manualDownloadResourceElements) {
|
||||
@@ -22,7 +22,7 @@ webviewLib.setupResourceManualDownload = function() {
|
||||
element.addEventListener('click', webviewLib.onUnloadedResourceClick);
|
||||
manualDownloadResourceElements.push(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.handleInternalLink = function(event, anchorNode) {
|
||||
const href = anchorNode.getAttribute('href');
|
||||
@@ -34,26 +34,27 @@ webviewLib.handleInternalLink = function(event, anchorNode) {
|
||||
|
||||
location.hash = href;
|
||||
|
||||
// HACK
|
||||
// HACK
|
||||
// For some reason anchors at the bottom cause the webview to move itself
|
||||
// so that the content is aligned with the top of the screen
|
||||
// This basically refreshes the scroll view so that is returns to a normal
|
||||
// position, the scroll positions stays correct though
|
||||
// Additionally an anchor could not be clicked twice because the location
|
||||
// would not change, this fixes that also
|
||||
setTimeout(function() { location.hash = old_hash; }, 10);
|
||||
setTimeout(function() {
|
||||
location.hash = old_hash;
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.getParentAnchorElement = function(element) {
|
||||
let counter = 0;
|
||||
while (true) {
|
||||
|
||||
if (counter++ >= 10000) {
|
||||
console.warn('been looping for too long - exiting')
|
||||
console.warn('been looping for too long - exiting');
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -61,14 +62,14 @@ webviewLib.getParentAnchorElement = function(element) {
|
||||
if (element.nodeName === 'A') return element;
|
||||
element = element.parentElement;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.cloneError = function(error) {
|
||||
return {
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
stack: error.stack,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.logEnabledEventHandler = function(fn) {
|
||||
return function(event) {
|
||||
@@ -78,12 +79,12 @@ webviewLib.logEnabledEventHandler = function(fn) {
|
||||
webviewLib.options_.postMessage('error:' + JSON.stringify(webviewLib.cloneError(error)));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
webviewLib.initialize = function(options) {
|
||||
webviewLib.options_ = options;
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', function(event) {
|
||||
const anchor = webviewLib.getParentAnchorElement(event.target);
|
||||
@@ -107,4 +108,3 @@ document.addEventListener('click', function(event) {
|
||||
if (webviewLib.handleInternalLink(event, anchor)) return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user