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

Add plugin local asset collection #1129

Merged
merged 4 commits into from
Apr 11, 2020

Conversation

ang-zeyu
Copy link
Contributor

@ang-zeyu ang-zeyu commented Mar 16, 2020

What is the purpose of this pull request? (put "X" next to an item, remove the rest)

• [x] Documentation update
• [x] Enhancement to an existing feature

Resolves #839

#442 - fixed with stopPropagation instead of relying on runtime window.location.href shifting
#433's hiding/displaying of anchor icons - done using css instead

What is the rationale for this request?

There is some degree of logic within the markbind core code that is related to plugins.
This is because the plugin getLinks and getScripts methods only allow linking to external sources.

We can enhance the API hence, allowing us to encapsulate plugin logic within itself, which should lead to better code readability.

What changes did you make? (Give an overview)
Commit organization:

  1. Add local plugin asset collection, and small update to docs accordingly
  2. Encapsulate markbind-plugin-anchors using this new feature
  3. Add and update tests for (1)
  4. Update tests for (2)

Is there anything you'd like reviewers to focus on?
Was there a reason #433 was done using runtime jQuery?

Testing instructions:

  • npm run test should pass

Proposed commit message: (wrap lines at 72 characters)
Add local asset collection for plugins

Plugins might want to package their own assets for use instead of
relying on external sources only.
The main markbind code also has some amount of logic and styles
relating to the anchor plugin.

Let's add this, allowing the getLinks and getScripts methods to return
link and script elements that have a relative or absolute file path as
its src or href attributes.
Let's encapsulate the anchor plugin's logic and styles within the
plugin itself, which should lead to better code readability.
This also allows the user to turn off the plugin without risk of side
effects.

@ang-zeyu ang-zeyu force-pushed the encapsulate-anchor-plugin branch 3 times, most recently from 3a1202e to a4f55ac Compare March 23, 2020 10:21
@le0tan le0tan added the pr.Enhancement 📈 Enhancement to an existing feature label Mar 29, 2020
@ang-zeyu ang-zeyu force-pushed the encapsulate-anchor-plugin branch 2 times, most recently from cd2227a to a17c456 Compare March 31, 2020 15:09
src/Page.js Outdated
@@ -983,6 +984,28 @@ class Page {
* Collect page content inserted by plugins
*/
collectPluginsAssets(content) {
const getResolvedAssetElement = (html, tagName, attrName, plugin, pluginName) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only one suggestion:

The implementation of utils.buildScript and buildStyleSheet plus this getResolvedElement seems rather redundant, where build* produces <script src =...></script>, and getResolvedElement later reparses it. If buildScript could instead return something like

{ type: 'scriptsrc', src: 'file.js' }

then we wouldn't need to use cheerio at all, just convert the src first and then return <script src =convertedsrc.js></script>.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One con with this suggestion would be that the user cannot manually return <script src = path></script>.

Maybe it's better to leave it in so the user has more choices?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked the buildScript/buildStylesheet a little with the new pluginUtils from #1100, its the same from a plugin author's standpoint though ( changes are limited to the first of the 4 commits ).

{ type: 'scriptsrc', src: 'file.js' }

for this, I think returning <script/link> directly is more intuitive from a plugin standpoint, since we represent html in html and not in json. This way the author can also add other variables to the tag as well easily, e.g. <link prefetch ... />.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, but now the user has to use buildScript if they want an external link.

So they can't add other attributes like <link prefetch href = "externa.css" />.

The first implementation is probably better

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, reverted that. ( getResolvedAssetElement is able to stay in pluginUtils though )

@openorclose
Copy link
Contributor

Nice refactor!

LGTM, only one small suggestion.

@ang-zeyu ang-zeyu force-pushed the encapsulate-anchor-plugin branch 2 times, most recently from a6f73ab to a7420c0 Compare April 2, 2020 07:29
@ang-zeyu
Copy link
Contributor Author

ang-zeyu commented Apr 5, 2020

@marvinchin could I get your thoughts here as well? since you opened up #839 =)

The main change here being letting plugins add local assets instead of just ones from external cdns ( first of the 4 commits )

@marvinchin
Copy link
Contributor

Sorry for the delays 🙏 I'll look at this tomorrow!

@ang-zeyu
Copy link
Contributor Author

ang-zeyu commented Apr 6, 2020

Sorry for the delays 🙏 I'll look at this tomorrow!

No rush, not in a hurry to get this merged! 😄

Copy link
Contributor

@nbriannl nbriannl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rebase your PR 🙂

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation mostly looks good to me, just a couple of comments.

src/Page.js Outdated
this.frontMatter, linkUtils);
let pluginLinks = plugin.getLinks(content, this.pluginsContext[pluginName],
this.frontMatter, linkUtils);
pluginLinks = pluginLinks.map(linkHtml => getResolvedAssetElement(linkHtml, this.baseUrl,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep pluginLinks and const and delcare a new const resolvedPluginLinks instead?

@@ -50,4 +53,42 @@ const pluginUtil = {
},
};

module.exports = pluginUtil;
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intention of pluginUtil is to contain a set of useful functions for plugin writers to use. getResolvedAssetElement seems to be something more internal to how markbind handles assets from plugins, and does not need to be exposed to plugin writers. So maybe it should belong somewhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved it back to page

@@ -13,63 +13,47 @@ function scrollToUrlAnchorHeading() {
}
}

function flattenModals() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm - this isn't needed anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, its a leftover from the bootstrap-vue PR

src/Site.js Outdated
this.plugins[plugin]._pluginAssetOutputPath = path.resolve(this.outputPath,
PLUGIN_SITE_ASSET_FOLDER_NAME, plugin);

fs.mkdirSync(this.plugins[plugin]._pluginAssetOutputPath, { recursive: true });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if plugins have assets, the sources might be urls right? In that case, there might not be any assets copied to the output folder. Should we defer the creation of the folder until the point that we are copying it over?

@marvinchin
Copy link
Contributor

Also just to note, this PR could have been split into two parts - one adding support for local assets, and then the other one using it to fix markbind-plugin-anchors 🙂 This way each PR could be focused and easier to review. Not necessary to split them up now though!

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@marvinchin marvinchin added this to the v2.13.2 milestone Apr 10, 2020
@ang-zeyu
Copy link
Contributor Author

ang-zeyu commented Apr 11, 2020

@nbriannl need you to remove the change request =X


updated below on latest, no changes

@ang-zeyu ang-zeyu force-pushed the encapsulate-anchor-plugin branch 2 times, most recently from dfab13c to 1fadfbb Compare April 11, 2020 07:39
Plugins might want to package their own assets for use instead of
relying on external sources only.

Let's add this, allowing the getLinks and getScripts methods to return
link and script elements that have a relative or absolute file path as
its src or href attributes.
The main markbind code has some amount of logic and styles relating to
the anchor plugin.

Let's encapsulate the anchor plugin's logic and styles within the
plugin itself, which should lead to better code readability.
This also allows the user to turn off the plugin without risk of side
effects.
@ang-zeyu ang-zeyu merged commit 248898d into MarkBind:master Apr 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr.Enhancement 📈 Enhancement to an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow plugins to add assets
5 participants