From c39c354b87d24060b2c4f2e20f13a2bf4a9f6fcf Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Wed, 4 Mar 2020 03:59:01 +0800 Subject: [PATCH] Fix baseUrl not working in include src attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While pre-processing includes or panels, we have not yet resolved the baseUrl of the src attribute. This causes markbind to fail in finding the source file, since baseUrl remains in the src attribute. Let’s resolve the baseUrl for such cases first, allowing the user to use the baseUrl attribute in include and panel src attributes. --- src/Page.js | 1 + .../preprocessors/componentPreprocessor.js | 20 ++++++++-- test/functional/test_site/expected/index.html | 38 ++++++++++++++++++- .../SpecifyingRequirements._include_.html | 18 +++++++++ .../testBaseUrlInIncludeSrc._include_.html | 3 ++ .../expected/sub_site/index._include_.html | 3 +- .../test_site/expected/sub_site/index.html | 4 +- ...tBaseUrlInIncludeSrcSubSite._include_.html | 2 + test/functional/test_site/index.md | 20 ++++++++++ .../requirements/testBaseUrlInIncludeSrc.md | 1 + test/functional/test_site/sub_site/index.md | 2 + .../testBaseUrlInIncludeSrcSubSite.md | 1 + 12 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 test/functional/test_site/expected/requirements/SpecifyingRequirements._include_.html create mode 100644 test/functional/test_site/expected/requirements/testBaseUrlInIncludeSrc._include_.html create mode 100644 test/functional/test_site/expected/sub_site/testBaseUrlInIncludeSrcSubSite._include_.html create mode 100644 test/functional/test_site/requirements/testBaseUrlInIncludeSrc.md create mode 100644 test/functional/test_site/sub_site/testBaseUrlInIncludeSrcSubSite.md diff --git a/src/Page.js b/src/Page.js index d8483132ed..6e90d83232 100644 --- a/src/Page.js +++ b/src/Page.js @@ -1060,6 +1060,7 @@ class Page { .then(result => this.postRender(result)) .then(result => this.collectPluginsAssets(result)) .then(result => markbinder.processDynamicResources(file, result)) + .then(result => MarkBind.unwrapIncludeSrc(result)) .then((result) => { // resolve the site base url here const { relative } = urlUtils.getParentSiteAbsoluteAndRelativePaths(file, this.rootPath, diff --git a/src/lib/markbind/src/preprocessors/componentPreprocessor.js b/src/lib/markbind/src/preprocessors/componentPreprocessor.js index cf3fc6e829..ef2f9fe607 100644 --- a/src/lib/markbind/src/preprocessors/componentPreprocessor.js +++ b/src/lib/markbind/src/preprocessors/componentPreprocessor.js @@ -108,9 +108,23 @@ function _getSrcFlagsAndFilePaths(element, context, config) { // We do this even if the src is not a url to get the hash, if any const includeSrc = url.parse(element.attribs.src); - const filePath = isUrl - ? element.attribs.src - : path.resolve(path.dirname(context.cwf), decodeURIComponent(includeSrc.path)); + const baseUrlRegex = new RegExp('^{{\\s*baseUrl\\s*}}[/\\\\]'); + + let filePath; + if (isUrl) { + filePath = element.attribs.src; + } else { + const includePath = decodeURIComponent(includeSrc.path); + + if (baseUrlRegex.test(includePath)) { + // The baseUrl has not been resolved during pre-processing, but we need the source file path + const parentSitePath = urlUtils.getParentSiteAbsolutePath(context.cwf, config.rootPath, + config.baseUrlMap); + filePath = path.resolve(parentSitePath, includePath.replace(baseUrlRegex, '')); + } else { + filePath = path.resolve(path.dirname(context.cwf), includePath); + } + } const boilerplateFilePath = _getBoilerplateFilePath(element, config, filePath); const actualFilePath = boilerplateFilePath || filePath; diff --git a/test/functional/test_site/expected/index.html b/test/functional/test_site/expected/index.html index f8b5285162..64785b4b8e 100644 --- a/test/functional/test_site/expected/index.html +++ b/test/functional/test_site/expected/index.html @@ -338,7 +338,9 @@

Feature list<
  • Versus play – Two players can play against each other.
  • Timer – Additional fixed time restriction on the player.
  • - +
    +
    +

    This is a page from another Markbind site. The purpose of this page is to ensure that reuse works as expected. All the following images should display correctly.

    Some variables:

    @@ -401,6 +403,40 @@

    Feature list<

    +

    Include a file using baseUrl

    +
    +

    As we establish requirements, they should be recorded in some way for future reference, usually called a requirement specification. Furthermore, it is advisable to show these requirements to stakeholders, and refine requirements based on their + feedback. The next phase is to convert requirements into a product specification that specifies how the product will address the requirements.

    +
    + +

    Include a file in a sub-folder that uses baseUrl

    +
    +
    +

    Requirements gathering, requirements elicitation, requirements analysis, requirements capture are some of the terms commonly and interchangeably used to represent the activity of understanding what a software product should + do.

    +
    +
    + +

    Include a file in a sub-folder that uses baseUrl using baseUrl

    +
    +
    +

    Requirements gathering, requirements elicitation, requirements analysis, requirements capture are some of the terms commonly and interchangeably used to represent the activity of understanding what a software product should + do.

    +
    +
    + +

    Include a file in a sub-site that uses baseUrl

    +
    +
    +
    +
    + +

    Include a file in a sub-site that uses baseUrl using baseUrl

    +
    +
    +
    +
    +

    Trimmed include

    Fragment with leading spaces and newline

    Trimmed include fragment

    diff --git a/test/functional/test_site/expected/requirements/SpecifyingRequirements._include_.html b/test/functional/test_site/expected/requirements/SpecifyingRequirements._include_.html new file mode 100644 index 0000000000..352bb5ca51 --- /dev/null +++ b/test/functional/test_site/expected/requirements/SpecifyingRequirements._include_.html @@ -0,0 +1,18 @@ +

    Specifying requirements

    +

    + As we establish requirements, they should be recorded in some way for future reference, usually called a requirement specification. Furthermore, it is advisable to show these requirements to stakeholders, and refine requirements based on their feedback. + The next phase is to convert requirements into a product specification that specifies how the product will address the requirements. +

    +

    Given next are some tools and techniques that can be used to specify requirements. Note that they can also be used for establishing requirements too.

    +

    Textual descriptions (unstructured prose)

    +

    This is the most straight forward way of describing requirements. A textual description can be used to give a quick overview of the domain/system that is understandable to both the users and the development team. Textual descriptions are especially useful + when describing the vision of a product. However, lengthy textual descriptions are hard to follow.

    +

    Feature list

    +

    It is a list of features (or functionalities) grouped according to some criteria such as priority (e.g. must-have, nice-to-have, etc. ), order of delivery, object or process related (e.g. order-related, invoice-related, etc.). Here is a sample feature + list from Minesweeper (only a brief description has been provided to save space).

    +
      +
    1. Basic play – Single player play.
    2. +
    3. Difficulty levels – Additional Medium and Advanced levels.
    4. +
    5. Versus play – Two players can play against each other.
    6. +
    7. Timer – Additional fixed time restriction on the player.
    8. +
    \ No newline at end of file diff --git a/test/functional/test_site/expected/requirements/testBaseUrlInIncludeSrc._include_.html b/test/functional/test_site/expected/requirements/testBaseUrlInIncludeSrc._include_.html new file mode 100644 index 0000000000..651f4d6ade --- /dev/null +++ b/test/functional/test_site/expected/requirements/testBaseUrlInIncludeSrc._include_.html @@ -0,0 +1,3 @@ +
    +

    Requirements gathering, requirements elicitation, requirements analysis, requirements capture are some of the terms commonly and interchangeably used to represent the activity of understanding what a software product should do.

    +
    \ No newline at end of file diff --git a/test/functional/test_site/expected/sub_site/index._include_.html b/test/functional/test_site/expected/sub_site/index._include_.html index da17da8813..88c699b5b3 100644 --- a/test/functional/test_site/expected/sub_site/index._include_.html +++ b/test/functional/test_site/expected/sub_site/index._include_.html @@ -8,4 +8,5 @@

    Feature list<
  • Versus play – Two players can play against each other.
  • Timer – Additional fixed time restriction on the player.
  • - \ No newline at end of file +
    +
    \ No newline at end of file diff --git a/test/functional/test_site/expected/sub_site/index.html b/test/functional/test_site/expected/sub_site/index.html index 3d292a122a..527cfa59bf 100644 --- a/test/functional/test_site/expected/sub_site/index.html +++ b/test/functional/test_site/expected/sub_site/index.html @@ -35,7 +35,9 @@

    Feature list<
  • Versus play – Two players can play against each other.
  • Timer – Additional fixed time restriction on the player.
  • - +
    +
    +