From 3d662a5bf71bbfef077cfbc478df241d794f55a0 Mon Sep 17 00:00:00 2001 From: Anix Date: Wed, 20 May 2020 11:14:26 +0000 Subject: [PATCH] fix: fixed target and rel issue (fixes #1183) --- packages/docsify-server-renderer/index.js | 4 +- src/core/event/scroll.js | 2 +- src/core/global-api.js | 4 +- src/core/render/compiler.js | 5 +- src/core/render/compiler/link.js | 25 +++- src/core/render/embed.js | 2 +- src/core/render/index.js | 2 +- test/unit/base.test.js | 2 +- test/unit/render.test.js | 164 ++++++++++++---------- test/unit/util.test.js | 2 +- 10 files changed, 117 insertions(+), 95 deletions(-) diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index 0d87dffdd..e6f5f9666 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -1,13 +1,13 @@ import { readFileSync } from 'fs'; import { resolve, basename } from 'path'; import resolvePathname from 'resolve-pathname'; +import fetch from 'node-fetch'; +import debug from 'debug'; import { AbstractHistory } from '../../src/core/router/history/abstract'; import { Compiler } from '../../src/core/render/compiler'; import { isAbsolutePath } from '../../src/core/router/util'; import * as tpl from '../../src/core/render/tpl'; import { prerenderEmbed } from '../../src/core/render/embed'; -import fetch from 'node-fetch'; -import debug from 'debug'; function cwd(...args) { return resolve(process.cwd(), ...args); diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index 47d64b417..946589996 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -1,8 +1,8 @@ +import Tweezer from 'tweezer.js'; import { isMobile } from '../util/env'; import * as dom from '../util/dom'; import { removeParams } from '../router/util'; import config from '../config'; -import Tweezer from 'tweezer.js'; const nav = {}; let hoverOver = false; diff --git a/src/core/global-api.js b/src/core/global-api.js index 5529bdaf3..189309af0 100644 --- a/src/core/global-api.js +++ b/src/core/global-api.js @@ -1,10 +1,10 @@ +import prism from 'prismjs'; +import marked from 'marked'; import * as util from './util'; import * as dom from './util/dom'; import { Compiler } from './render/compiler'; import { slugify } from './render/slugify'; import { get } from './fetch/ajax'; -import prism from 'prismjs'; -import marked from 'marked'; export default function() { window.Docsify = { diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index 5cb8f9e5a..4eaf51215 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -1,3 +1,4 @@ +import marked from 'marked'; import { isAbsolutePath, getPath, getParentPath } from '../router/util'; import { isFn, merge, cached, isPrimitive } from '../util/core'; import { tree as treeTpl } from './tpl'; @@ -11,7 +12,6 @@ import { paragraphCompiler } from './compiler/paragraph'; import { taskListCompiler } from './compiler/taskList'; import { taskListItemCompiler } from './compiler/taskListItem'; import { linkCompiler } from './compiler/link'; -import marked from 'marked'; const cachedLinks = {}; @@ -193,7 +193,7 @@ export class Compiler { _initRenderer() { const renderer = new marked.Renderer(); - const { linkTarget, router, contentBase } = this; + const { linkTarget, linkRel, router, contentBase } = this; const _self = this; const origin = {}; @@ -233,6 +233,7 @@ export class Compiler { renderer, router, linkTarget, + linkRel, compilerClass: _self, }); origin.paragraph = paragraphCompiler({ renderer }); diff --git a/src/core/render/compiler/link.js b/src/core/render/compiler/link.js index 71246bb15..22ff59d07 100644 --- a/src/core/render/compiler/link.js +++ b/src/core/render/compiler/link.js @@ -1,11 +1,21 @@ import { getAndRemoveConfig } from '../utils'; import { isAbsolutePath } from '../../router/util'; -export const linkCompiler = ({ renderer, router, linkTarget, compilerClass }) => +export const linkCompiler = ({ + renderer, + router, + linkTarget, + linkRel, + compilerClass, +}) => (renderer.link = (href, title = '', text) => { let attrs = []; const { str, config } = getAndRemoveConfig(title); - + linkTarget = config.target || linkTarget; + linkRel = + linkTarget === '_blank' + ? compilerClass.config.externalLinkRel || 'noopener' + : ''; title = str; if ( @@ -24,10 +34,13 @@ export const linkCompiler = ({ renderer, router, linkTarget, compilerClass }) => document.URL.replace(/\/(?!.*\/).*/, '/').replace('#/./', '') + href; } attrs.push(href.indexOf('mailto:') === 0 ? '' : `target="${linkTarget}"`); - } - - if (config.target) { - attrs.push(`target="${config.target}"`); + attrs.push( + href.indexOf('mailto:') === 0 + ? '' + : linkRel !== '' + ? ` rel="${linkRel}"` + : '' + ); } // special case to check crossorigin urls diff --git a/src/core/render/embed.js b/src/core/render/embed.js index 8b84c7acb..55a7fec35 100644 --- a/src/core/render/embed.js +++ b/src/core/render/embed.js @@ -1,6 +1,6 @@ +import stripIndent from 'strip-indent'; import { get } from '../fetch/ajax'; import { merge } from '../util/core'; -import stripIndent from 'strip-indent'; const cached = {}; diff --git a/src/core/render/index.js b/src/core/render/index.js index 9b50dc708..37cd6af34 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -1,4 +1,5 @@ /* eslint-disable no-unused-vars */ +import tinydate from 'tinydate'; import * as dom from '../util/dom'; import cssVars from '../util/polyfill/css-vars'; import { callHook } from '../init/lifecycle'; @@ -10,7 +11,6 @@ import { scrollActiveSidebar } from '../event/scroll'; import { Compiler } from './compiler'; import * as tpl from './tpl'; import { prerenderEmbed } from './embed'; -import tinydate from 'tinydate'; function executeScript() { const script = dom diff --git a/test/unit/base.test.js b/test/unit/base.test.js index 736b70ac6..ed050424a 100644 --- a/test/unit/base.test.js +++ b/test/unit/base.test.js @@ -2,8 +2,8 @@ require = require('esm')( module /* , options */ ); /* eslint-disable-line no-global-assign */ -const { History } = require('../../src/core/router/history/base'); const { expect } = require('chai'); +const { History } = require('../../src/core/router/history/base'); class MockHistory extends History { parse(path) { diff --git a/test/unit/render.test.js b/test/unit/render.test.js index 9a7163024..28e88ac0e 100644 --- a/test/unit/render.test.js +++ b/test/unit/render.test.js @@ -1,5 +1,5 @@ -const { init, expectSameDom } = require('../_helper'); const { expect } = require('chai'); +const { init, expectSameDom } = require('../_helper'); describe('render', function() { it('important content (tips)', async function() { @@ -14,88 +14,81 @@ describe('render', function() { it('as unordered task list', async function() { const { docsify } = await init(); const output = docsify.compiler.compile(` -- [x] Task 1 -- [ ] Task 2 -- [ ] Task 3`); + - [x] Task 1 + - [ ] Task 2 + - [ ] Task 3`); expect( output, `` +
  • +
  • +
  • + ` ); }); it('as ordered task list', async function() { const { docsify } = await init(); const output = docsify.compiler.compile(` -1. [ ] Task 1 -2. [x] Task 2`); + 1. [ ] Task 1 + 2. [x] Task 2`); expectSameDom( output, `
      -
    1. -
    2. -
    ` +
  • +
  • + ` ); }); it('normal unordered', async function() { const { docsify } = await init(); const output = docsify.compiler.compile(` -- [linktext](link) -- just text`); + - [linktext](link) + - just text`); expectSameDom( output, `` +
  • linktext
  • +
  • just text
  • + ` ); }); it('unordered with custom start', async function() { const { docsify } = await init(); const output = docsify.compiler.compile(` -1. first -2. second + 1. first + 2. second -text + text -3. third`); + 3. third`); expectSameDom( output, - `
      -
    1. first
    2. -
    3. second
    4. -
    -

    text

    -
      -
    1. third
    2. -
    ` + `
    1. first

    2. second

      text

    3. third

    ` ); }); it('nested', async function() { const { docsify } = await init(); const output = docsify.compiler.compile(` -- 1 -- 2 - - 2 a - - 2 b -- 3`); + - 1 + - 2 + - 2 a + - 2 b + - 3`); expectSameDom( output, `` +
  • 1
  • +
  • 2 +
  • +
  • 3
  • + ` ); }); }); @@ -181,11 +174,11 @@ text expectSameDom( output, ` -

    - - h1 tag - -

    ` +

    + + h1 tag + +

    ` ); }); @@ -195,11 +188,11 @@ text expectSameDom( output, ` -

    - - h2 tag - -

    ` +

    + + h2 tag + +

    ` ); }); @@ -209,11 +202,11 @@ text expectSameDom( output, ` -

    - - h3 tag - -

    ` +

    + + h3 tag + +

    ` ); }); @@ -223,11 +216,11 @@ text expectSameDom( output, ` -

    - - h4 tag - -

    ` +

    + + h4 tag + +

    ` ); }); @@ -237,11 +230,11 @@ text expectSameDom( output, ` -
    - - h5 tag - -
    ` +
    + + h5 tag + +
    ` ); }); @@ -251,11 +244,11 @@ text expectSameDom( output, ` -
    - - h6 tag - -
    ` +
    + + h6 tag + +
    ` ); }); }); @@ -267,7 +260,22 @@ text expectSameDom( output, - '

    alt text

    ' + '

    alt text

    ' + ); + }); + + it('linkrel', async function() { + const { docsify } = await init('default', { + externalLinkTarget: '_blank', + externalLinkRel: 'noopener', + }); + const output = docsify.compiler.compile( + '[alt text](http://www.example.com)' + ); + + expectSameDom( + output, + '

    alt text

    ' ); }); @@ -279,7 +287,7 @@ text expectSameDom( output, - '

    alt text

    ' + '

    alt text

    ' ); }); @@ -291,7 +299,7 @@ text expectSameDom( output, - '

    alt text

    ' + '

    alt text

    ' ); }); @@ -303,7 +311,7 @@ text expectSameDom( output, - '

    alt text

    ' + '

    alt text

    ' ); }); @@ -315,7 +323,7 @@ text expectSameDom( output, - '

    alt text

    ' + '

    alt text

    ' ); }); }); diff --git a/test/unit/util.test.js b/test/unit/util.test.js index e4e8a0e3b..9dadf28a3 100644 --- a/test/unit/util.test.js +++ b/test/unit/util.test.js @@ -2,8 +2,8 @@ require = require('esm')( module /* , options */ ); /* eslint-disable-line no-global-assign */ -const { resolvePath } = require('../../src/core/router/util'); const { expect } = require('chai'); +const { resolvePath } = require('../../src/core/router/util'); describe('router/util', function() { it('resolvePath', async function() {