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

Menu links not displaying router-link-active #1732

Open
1 task done
Mbensler opened this issue Jul 31, 2019 · 7 comments
Open
1 task done

Menu links not displaying router-link-active #1732

Mbensler opened this issue Jul 31, 2019 · 7 comments
Labels
type: question or discussion Question or discussion

Comments

@Mbensler
Copy link

  • I confirm that this is an issue rather than a question.

Bug report

When using letters like Æ, Ø, Å in the menu text and menu links, the header active bottom border will not display. When using normal english characters in the text and links it works how it's supposed to.

Steps to reproduce

Use letters like Æ, Ø or Å in the nav menu text.

What is expected?

The border-bottom router-link-active should display normally with the Æ, Ø, Å letters just like it does with normal text characters.

What is actually happening?

The router-link-active (bottom border) isn't displaying when using weird characters.

Other relevant information

  • Output of npx vuepress info in my VuePress project:

Environment Info:

System:
OS: Linux 5.2 Arch Linux undefined
CPU: (8) x64 Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz
Binaries:
Node: 11.15.0 - /usr/bin/node
Yarn: 1.17.3 - /usr/bin/yarn
npm: 6.10.2 - /usr/bin/npm
Browsers:
Chrome: Not Found
Firefox: 68.0.1
npmPackages:
@vuepress/core: Not Found
@vuepress/theme-default: Not Found
vuepress: Not Found
npmGlobalPackages:
vuepress: 1.0.2

@chris-visser
Copy link

After some investigation, this turns out to be a vue-router issue. The problem lies in the string comparison features of default Javascript. A similar issue is described on this Stackoverflow page:

https://stackoverflow.com/questions/10805711/javascript-string-comparison-fails-when-comparing-unicode-characters.

Since it takes a whole library just to add this functionality into the Vue router, it might become a router plugin or something, but I would recommend using kebabCase / slugCase formats when it comes to files and have the titles be user-friendly.

@posva Do you have some thoughts about this?

Here's the actual Vue Router snippet that does the comparison:

function isObjectEqual (a, b) {
  if ( a === void 0 ) a = {};
  if ( b === void 0 ) b = {};

  // handle null value #1566
  if (!a || !b) { return a === b }
  var aKeys = Object.keys(a);
  var bKeys = Object.keys(b);
  if (aKeys.length !== bKeys.length) {
    return false
  }
  return aKeys.every(function (key) {
    var aVal = a[key];
    var bVal = b[key];
    // check nested equality
    if (typeof aVal === 'object' && typeof bVal === 'object') {
      return isObjectEqual(aVal, bVal)
    }
    return String(aVal) === String(bVal)
  })
}

@posva
Copy link
Member

posva commented Aug 6, 2019

I don't understand very well what behavior is failing in Vue Router as a route with unicode is matched correctly and applies the active classes. Maybe there is a case that we didn't handle and in that case I will need a boiled down repro to check it

@Mbensler
Copy link
Author

Mbensler commented Aug 6, 2019

Thanks for the answers.

Small update to the problem:

After having tested it further, I've noticed that using unicode characters in the menu text CAN actually work, but only if you DON'T use unicode characters in the link. I am in a situation where I need to be able to use unicode chars in both the text and the link.

I've made a repo with some short descriptions that may or may not help you. I think I've probably explained it well enough/shown it for you to get what I mean.

https://github.com/Mbensler/testvuepress

So to sum it up: I can make it work with unicode characters like Æ, Ø, Å in the menu text, but not if i also use it in the link text(folder names), which is what i need.

I appreciate the help.

@chris-visser
Copy link

@posva is right. (thanks btw). I've tested it with the vue-router examples. I will dive a bit deeper. vuepress doesn't seem to do any custom matching..

Screenshot from 2019-08-06 21-38-25

@posva
Copy link
Member

posva commented Aug 6, 2019

please, let me know if you find something we need to fix on vue-router!

@chris-visser
Copy link

I've found the issue and the fix. The issue is related to ./package/@vuepress/core/lib/node/Page.js. All scanned filepaths are 'fixed' with encodeURI meaning the special chars get converted to their encoded form. This doesnt happen with the link's uri, that's why it does show the correct file, but its not matching it for the link to make it an active state.

Here's a snippet of that code:

    if (relative) {
      this.regularPath = encodeURI(fileToPath(relative))
    } else if (_path) {
      this.regularPath = encodeURI(_path)
    } else if (permalink) {
      this.regularPath = encodeURI(permalink)
    }

It could ofcourse be fixed by removing the encodeURI. However, there is a test explicitly checking if the paths are properly encoded, meaning that this might break existing dependants.

@ulivz To you have an idea of the impact that this change would bring? If it does have a breaking impact, I might add a PR with some config approach to make exceptions.

@chris-visser
Copy link

Found a nice workaround for now @Mbensler .

You can use permalinks in your frontmatter. For example in your README.md:

---
permalink: /theÅme
---

This would put the permalink as the matcher for the url and it will become active. Unfortunatly only for exact matches so you will need to add it to every sub readme file:

---
permalink: /theÅme/someintro.md
---

@ulivz ulivz added the type: question or discussion Question or discussion label Sep 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Question or discussion
Projects
None yet
Development

No branches or pull requests

4 participants