Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configs to be functions #1189

Merged
merged 21 commits into from Jun 13, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f72bf4c
allow the user's $docsify config to be a function that receives as in…
trusktr May 22, 2020
b4b8bdc
add tests to make sure the global and plugin APIs are available and t…
trusktr May 22, 2020
732c34d
add editorconfig (tells editors which basic text format to use)
trusktr May 22, 2020
5a5b5aa
update docs regarding configs as functions
trusktr May 22, 2020
b72cb3d
add build error handling so builds don't silently fail
trusktr May 23, 2020
7e002bf
feat: update src/core/index.js to export all global APIs, deprecate o…
trusktr May 23, 2020
b40baae
Merge pull request #1195 from docsifyjs/deprecate-old-globals-and-mak…
trusktr May 23, 2020
1b8a81a
Merge pull request #1192 from docsifyjs/add-build-error-handling
trusktr May 23, 2020
88033b6
remove the DOCSIFY global made by Rollup, and move Docsify into a sep…
trusktr Jun 7, 2020
79fe3d5
remove some unused code and accept eslint changes
trusktr Jun 7, 2020
dca22f3
simplify import
trusktr Jun 7, 2020
41dc2c7
ensure that the test script runs a prod build
trusktr Jun 7, 2020
31f1a64
update outdated comment
trusktr Jun 7, 2020
63f1b88
Revert "ensure that the test script runs a prod build"
trusktr Jun 7, 2020
809fda9
Merge branch 'develop' into allow-config-function
trusktr Jun 7, 2020
72ec71f
Merge branch 'develop' into allow-config-function
trusktr Jun 8, 2020
0438dd6
Merge branch 'develop' into allow-config-function
trusktr Jun 9, 2020
64a231d
use a port for the tests that doesn't collide with common local serve…
trusktr Jun 10, 2020
abaf6f3
Merge branch 'develop' into allow-config-function
trusktr Jun 10, 2020
8f3f263
Merge branch 'develop' into allow-config-function
trusktr Jun 13, 2020
146e4c4
Update build/css.js
trusktr Jun 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions .editorconfig
@@ -0,0 +1,11 @@
# http://EditorConfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
anikethsaha marked this conversation as resolved.
Show resolved Hide resolved
20 changes: 19 additions & 1 deletion docs/configuration.md
@@ -1,6 +1,6 @@
# Configuration

You can configure the `window.$docsify`.
You can configure Docsify by defining `window.$docsify` as an object:

```html
<script>
Expand All @@ -12,6 +12,24 @@ You can configure the `window.$docsify`.
</script>
```

The config can also be defined as a function, in which case the first arg is the Docsify `vm` instance. The function should return a config object. This can be useful for referencing `vm` in places like the markdown configuration:

```html
<script>
window.$docsify = function(vm) {
return {
markdown: {
renderer: {
code(code, lang) {
// ... use `vm` ...
},
},
},
};
};
</script>
anikethsaha marked this conversation as resolved.
Show resolved Hide resolved
```

## el

- Type: `String`
Expand Down
6 changes: 4 additions & 2 deletions src/core/config.js
Expand Up @@ -2,7 +2,7 @@ import { merge, hyphenate, isPrimitive, hasOwn } from './util/core';

const currentScript = document.currentScript;

export default function() {
export default function(vm) {
const config = merge(
{
el: '#app',
Expand Down Expand Up @@ -35,7 +35,9 @@ export default function() {
relativePath: false,
topMargin: 0,
},
window.$docsify
typeof window.$docsify === 'function'
? window.$docsify(vm)
: window.$docsify
);

const script =
Expand Down
6 changes: 3 additions & 3 deletions src/core/index.js
Expand Up @@ -11,7 +11,7 @@ import initGlobalAPI from './global-api';
* @returns {Number|void} If the page is already laoded returns the result of the setTimeout callback,
* otherwise it only attaches the callback to the DOMContentLoaded event
*/
function ready(callback) {
export function documentReady(callback) {
anikethsaha marked this conversation as resolved.
Show resolved Hide resolved
const state = document.readyState;

if (state === 'complete' || state === 'interactive') {
Expand All @@ -21,7 +21,7 @@ function ready(callback) {
document.addEventListener('DOMContentLoaded', callback);
}

function Docsify() {
export function Docsify() {
this._init();
}

Expand All @@ -42,4 +42,4 @@ initGlobalAPI();
* Run Docsify
*/
// eslint-disable-next-line no-unused-vars
ready(_ => new Docsify());
documentReady(_ => new Docsify());
2 changes: 1 addition & 1 deletion src/core/init/index.js
Expand Up @@ -9,7 +9,7 @@ import { initLifecycle, callHook } from './lifecycle';
export function initMixin(proto) {
proto._init = function() {
const vm = this;
vm.config = config();
vm.config = config(vm);

initLifecycle(vm); // Init hooks
initPlugin(vm); // Install plugins
Expand Down
23 changes: 16 additions & 7 deletions test/_helper.js
Expand Up @@ -19,6 +19,21 @@ function ready(callback) {
document.addEventListener('DOMContentLoaded', callback);
}

module.exports.initJSDOM = initJSDOM;

/** @param {string} markup - The HTML document to initialize JSDOM with. */
function initJSDOM(markup, options = {}) {
const dom = new JSDOM(markup, options);

global.window = dom.window;
global.document = dom.window.document;
global.navigator = dom.window.navigator;
global.location = dom.window.location;
global.XMLHttpRequest = dom.window.XMLHttpRequest;

return dom;
}

module.exports.init = function(
fixture = 'default',
config = {},
Expand All @@ -39,15 +54,9 @@ module.exports.init = function(

const rootPath = path.join(__dirname, 'fixtures', fixture);

const dom = new JSDOM(markup);
const dom = initJSDOM(markup);
dom.reconfigure({ url: 'file:///' + rootPath });

global.window = dom.window;
global.document = dom.window.document;
global.navigator = dom.window.navigator;
global.location = dom.window.location;
global.XMLHttpRequest = dom.window.XMLHttpRequest;

// Mimic src/core/index.js but for Node.js
function Docsify() {
this._init();
Expand Down
101 changes: 101 additions & 0 deletions test/unit/docsify.test.js
@@ -0,0 +1,101 @@
/* eslint-disable no-global-assign */
require = require('esm')(module /* , options */);

const path = require('path');
const { expect } = require('chai');
const { initJSDOM } = require('../_helper');

const docsifySite = path.join(__dirname, '..', '..', 'docs');

const markup = /* html */ `<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app"></div>
</body>
</html>
`;

describe('Docsify public API', () => {
it('is available', async () => {
const DOM = initJSDOM(markup);
DOM.reconfigure({ url: 'file:///' + docsifySite });

const { documentReady } = require('../../src/core/index');
await new Promise(resolve => documentReady(resolve));

expect(typeof window.Docsify).to.equal('object');
expect(typeof window.Docsify.util).to.equal('object');
expect(typeof window.Docsify.dom).to.equal('object');
expect(typeof window.Docsify.get).to.equal('function');
expect(typeof window.Docsify.slugify).to.equal('function');
expect(typeof window.Docsify.version).to.equal('string');

expect(window.DocsifyCompiler).to.be.an.instanceof(Function);
expect(window.marked).to.be.an.instanceof(Function);
expect(typeof window.Prism).to.equal('object');
});
});

describe('Docsify config function', function() {
it('allows $docsify to be a function', async function() {
const DOM = initJSDOM(markup);
DOM.reconfigure({ url: 'file:///' + docsifySite });

window.configFunctionCalled = false;

window.$docsify = function(vm) {
// Check public API (that which is available at this point)
expect(vm).to.be.an.instanceof(Object);
expect(vm.constructor.name).to.equal('Docsify');
expect(vm.$fetch).to.be.an.instanceof(Function);
expect(vm.$resetEvents).to.be.an.instanceof(Function);
expect(vm.route).to.be.an.instanceof(Object);

window.configFunctionCalled = true;

return {};
};

const { documentReady, Docsify } = require('../../src/core/index');
await new Promise(resolve => documentReady(resolve));

new Docsify(); // eslint-disable-line

expect(window.configFunctionCalled).to.equal(true);
});

it('provides the hooks and vm API to plugins', async function() {
const DOM = initJSDOM(markup);
DOM.reconfigure({ url: 'file:///' + docsifySite });

window.pluginFunctionCalled = false;

window.$docsify = function(vm) {
const vm1 = vm;
return {
plugins: [
function(hook, vm2) {
expect(vm1).to.equal(vm2);

expect(hook.init).to.be.an.instanceof(Function);
expect(hook.beforeEach).to.be.an.instanceof(Function);
expect(hook.afterEach).to.be.an.instanceof(Function);
expect(hook.doneEach).to.be.an.instanceof(Function);
expect(hook.mounted).to.be.an.instanceof(Function);
expect(hook.ready).to.be.an.instanceof(Function);

window.pluginFunctionCalled = true;
},
],
};
};

const { documentReady, Docsify } = require('../../src/core/index');
await new Promise(resolve => documentReady(resolve));

new Docsify(); // eslint-disable-line

expect(window.pluginFunctionCalled).to.equal(true);
});
});