Skip to content

Allow xmlns= on <template> elements #27

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

Merged
merged 1 commit into from
Jul 9, 2018

Conversation

LukeShu
Copy link
Contributor

@LukeShu LukeShu commented Jul 7, 2018

  • Vue components are based on HTML5 custom elements. However, HTML5
    custom elements are required to be in the HTML namespace. This is not a
    requirement shared by Vue components. Vue itself doesn't care about the
    namespace of the elements that it is rendering (which will be determined
    at runtime based on the namespace of the parent element where it's being
    inserted). Therefore, it is desirable to communicate to linters and
    other tools what the intended namespace of a top-level <template> in an
    SFC is.

    See: https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition

  • Vue slots are based on HTML5 slots. However, because of the above
    limitation that HTML5 custom elements are always in the HTML5 namespace,
    the slots contained in them are also always in the HTML5 namespace.
    Because of Vue's flexibility on this, a Vue <slot> may appear in any
    namespace; content being rendered into a slot may end up in a different
    namespace than the namespace where it was parsed. Therefore, it is
    desirable to communicate to linters and other tools what the indented
    namespace is of content that will be rendered in a slot.

From these two observations, it would be useful to set xmlns= on:

  1. top-level <template> elements, and
  2. elements appearing in a slot.

The first is easy, but #2 has some concerns:

  • It's relatively difficult to determine when we're appearing in a slot.
    We could try checking for the slot= attribute, but that would miss cases
    where we use the default slot.
  • Because the xmlns= attribute on the resulting element would be invalid
    in HTML5 (in the cases where this is useful, anyway), we can't set it on
    normal elements anyway.

So, mostly because of the second reason, let's just say that to inform
linters about a change in namespace because of a slot, the contents must
be wrapped in a <template> to safely set xmlns= in a place that will be
ignored at runtime. So now we've revised that to allowing xmlns= on:

  1. top-level <template> elements, and
  2. <template> elements appearing in a slot.

Let's just make things simple and allow it for all <template> elements.
This means we'll be slightly too lax, and allow it on <template v-if="...">
constructs, but I'm OK with that.

As for which namespaces to consider valid, let's limit that to HTML, SVG,
and MathML, as those are the namespaces that are allowed in an HTML5
document.

 - Vue components are based on HTML5 custom elements.  However, HTML5
   custom elements are required to be in the HTML namespace.  This is not a
   requirement shared by Vue components.  Vue itself doesn't care about the
   namespace of the elements that it is rendering (which will be determined
   at runtime based on the namespace of the parent element where it's being
   inserted).  Therefore, it is desirable to communicate to linters and
   other tools what the intended namespace of a top-level <template> in an
   SFC is.

   See: https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition

 - Vue slots are based on HTML5 slots.  However, because of the above
   limitation that HTML5 custom elements are always in the HTML5 namespace,
   the slots contained in them are also always in the HTML5 namespace.
   Because of Vue's flexibility on this, a Vue <slot> may appear in any
   namespace; content being rendered into a slot may end up in a different
   namespace than the namespace where it was parsed.  Therefore, it is
   desirable to communicate to linters and other tools what the indented
   namespace is of content that will be rendered in a slot.

From these two observations, it would be useful to set xmlns= on:

 1. top-level <template> elements, and
 2. elements appearing in a slot.

The first is easy, but vuejs#2 has some concerns:

 - It's relatively difficult to determine when we're appearing in a slot.
   We could try checking for the slot= attribute, but that would miss cases
   where we use the default slot.
 - Because the xmlns= attribute on the resulting element would be invalid
   in HTML5 (in the cases where this is useful, anyway), we can't set it on
   normal elements anyway.

So, mostly because of the second reason, let's just say that to inform
linters about a change in namespace because of a slot, the contents must
be wrapped in a <template> to safely set xmlns= in a place that will be
ignored at runtime.  So now we've revised that to allowing xmlns= on:

 1. top-level <template> elements, and
 2. <template> elements appearing in a slot.

Let's just make things simple and allow it for all <template> elements.
This means we'll be slightly too lax, and allow it on <template v-if="...">
constructs, but I'm OK with that.

As for which namespaces to consider valid, let's limit that to HTML, SVG,
and MathML, as those are the namespaces that are allowed in an HTML5
document.
@codecov-io
Copy link

codecov-io commented Jul 7, 2018

Codecov Report

Merging #27 into master will increase coverage by <.01%.
The diff coverage is 88.88%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #27      +/-   ##
==========================================
+ Coverage   85.54%   85.55%   +<.01%     
==========================================
  Files          32       32              
  Lines        1847     1855       +8     
  Branches      476      481       +5     
==========================================
+ Hits         1580     1587       +7     
  Misses        181      181              
- Partials       86       87       +1
Impacted Files Coverage Δ
src/html/parser.ts 96.17% <88.88%> (-0.47%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7a9bde9...4a8b943. Read the comment docs.

LukeShu added a commit to LukeShu/eslint-plugin-vue that referenced this pull request Jul 7, 2018
…VG attribute

Several of the SVG attributes are canonically camel case or
hyphenated.  Verify that we correctly ignore those.

This depends on a change to vue-esplit-parser:
vuejs/vue-eslint-parser#27
@mysticatea
Copy link
Member

Sounds reasonable to me. Thank you for contributing!

@mysticatea mysticatea merged commit f6f42bb into vuejs:master Jul 9, 2018
LukeShu added a commit to LukeShu/eslint-plugin-vue that referenced this pull request Sep 4, 2018
…VG attribute

Several of the SVG attributes are canonically camel case or
hyphenated.  Verify that we correctly ignore those.

This depends on a change to vue-esplit-parser:
vuejs/vue-eslint-parser#27
which is present in v3.1.0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants