Lit-html: Using constructors as tag names

Created on 6 Dec 2017  Â·  33Comments  Â·  Source: Polymer/lit-html

I'd like to start a discussion on how one might be able to do the following:

import { html, render } from 'lit-html';
import MyComponent from './my-component';

render(html`<MyComponent></MyComponent>`, document.body);

There's some nice things we get from this.

Explicit usage

I stumbled across this while converting the Skate website to use Lit. It was previously using Preact, and I was doing something like the following to render my components.

<MyComponent.is />

In doing this, I was explicitly using the imported constructor to render components. When moving to Lit, I had to start explicitly defining my custom element names. More on why later. I had to do this because I couldn't infer the name from the constructor, I had to hard code it in the template literal.

My code ended up looking like:

import { html, render } from 'lit-html';
import `./my-component';

render(html`<my-component></my-component>`, document.body);

The problem here is that, in one file I could define a name. Since I'm not using the constructor, it may slip my mind to even import the component at the top. This actually caused a few weird issues because there were no errors about the constructor not being defined. The hardcoded name is valid, there's just no definition in the registry for it.

Dynamic custom element names

This is fantastic for testing components that don't have pre-defined names or apps that don't package their components to consumers, and simply use them internally. For example, in the Skate tests, we don't explicitly define the names of components. They're dynamic and we just new the constructor to use them. This way, we don't have to keep track of the names and manually ensure their uniqueness.

Similarly, apps don't need to worry about custom element names and they can just pass around constructors that they import. For these components, it'd be nice to not have to worry about naming. Though, the positive upside to naming is that you get better debugging.

However, when using Preact, we used to simply generate the name of the component from the class name of the custom element. We also have a { name } utility that will generate a unique name, given an optional hint. This allows us to have a base class that does something like:

import { name } from 'skatejs';

class Base extends HTMLElement {
  static get is() {
    return name(this.name);
  }
}

class Hello extends Base {}

// Registers: `x-hello`.
customElements.define(Hello.is, Hello);

We were doing this up until minifying the code broke the expected custom element name. The names were still valid when registered, but were different than what was being used in the literals.

Most helpful comment

@treshugart

That's a _really_ interesting snippet. I think it'll have to have it's own caching behavior to only do the setup work once, and it may be helpful to expose the interal litTag function: https://github.com/PolymerLabs/lit-html/blob/master/src/lit-html.ts#L45 which let's you provide your own tempalte cache.

I really like that this could be done on top of lit-html. I'd like to see more opinion and experiments layered this way. It's one reason why I made the lit-html vs lit-extended split - to signal that it's encouraged to make your own variant with different choices.

Would you be interested in experimenting with this in Skate?

If static were a thing, you could even have a small wrapper like this that wraps constructors in ...args with static(tag(Ctor)).

I was thinking that a tag() function would auto-wrap in static() internally, so all a wrapper would have to do is call tag().

I'll bump up the priority of static() since it has yet another use now.

@bgotink I think fixing up tag names at clone time it's going to be expensive and lead to some problem with custom elements reactions. We really want the tree to be as close to it's final state when constructors and connected callback hooks run. We _may_ be able to do the fixup at template prep time, but that still involves more reparenting that it's be good to avoid. If we have the requirement that tag names must be known at template prep time, which seems fine to me, we can do less work.

All 33 comments

having a generated name you register with customElements seems a bit dangerous to me

why not just do something like this?

import { html, render } from 'lit-html';
import MyComponent as MyOther from './my-component'; // only es6 class
customElements.define('my-other', MyOther);

render(html`<my-other></my-other>`, document.body);

That’s a lot of unnecessary ceremony for apps where you’re only using some
components internally. You literally never need to care about the name.
Sure, externalised components you’d probably not predefine. This is just a
nice-to-have. People coming from React-land will feel at home here.

I don’t want this use case to distract from the other point, though. Being
able to do this makes components easier to reason about because imports are
directly correlated to where they’re used.
On Wed, 6 Dec 2017 at 8:56 pm, Thomas Allmer notifications@github.com
wrote:

having a generated name you register with customElements seems a bit
dangerous to me

why not just do something like this?

import { html, render } from 'lit-html';
import MyComponent as MyOther from './my-component'; // only es6 class
customElements.define('my-other', MyOther);

render(html<my-other></my-other>, document.body);

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/PolymerLabs/lit-html/issues/217#issuecomment-349590255,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIVbBS5Pic9dPTzMUyomUY32zRzIikKks5s9mTGgaJpZM4Q3XIk
.

I’m also interested in why you think this is dangerous. You shouldn’t use it for components you package and ship to other consumers. Using it internally is no more dangerous than doing it manually. It’s actually safer because it will make sure that it’s unique. There’s no guarantee that what your brain picks will be.

I like the idea. I'm not sure that this can work though, right?

render(html`<MyComponent></MyComponent>`, document.body);

The string there is a string. Is this what you really wanted or did you mean to instead to have:

render(html`<${MyComponent}></${MyComponent}>`, document.body);

Yeah, there's a real implementation challenge here, give how lit-html works. The literal parts of a template have to form valid HTML, otherwise we'll get strange parsing behavior.

html`<${MyComponent}></${MyComponent}>`

Is not a valid lit template, because the HTML it produces is:

<{{}}></{{}}>

One way to fix this is with a static directive (and special support for it in core) that indicates a value should be interpolated _before_ building the HTML string, so you could do:

const tagName = 'my-element';
html`<${static(tagName)}></${static(tagName)}>`

Then you'd need a way to map from a constructor to a tag name. I think this is a bit out of scope for lit-html, but with static in place you could build it:

const tag = (ctor) => static(tagNameMap.get(ctor));

Then you could do:

html`<${tag(MyComponent)}></${tag(MyComponent)}>`

That isn't very ergonomic, but I think it's about the limit for what lit can do. Something that parses templates could _compile_ to lit-html of that form. Once you do that, you might want to use JSX, which can be made to compile to lit-html like this: https://www.npmjs.com/package/polyestr-tsx-lit-transform

To sketch out the idea, I've created a wrapper that essentially does what static would do internally. If static were a thing, you could even have a small wrapper like this that wraps constructors in ...args with static(tag(Ctor)) to reduce the API friction. The complexity would also be reduced because You wouldn't have (I think) O(n log n) + whatever lit is doing (this can probably be optimised to just O(n), though), you'd just have lit's overhead.

// Or lit-extended, of course.
import { html } from 'lit-html';

// This then wraps lit-html.
export function preLit(parts, ...args) {
  const newArgs = [];
  const newParts = parts.concat();
  const joinIndicies = [];

  // This creates a new list of parts and args to pass to Lit.
  for (let a = 0; a < args.length; a++) {
    const possibleCtor = args[a];

    // The `is` static prop is just used as an example of how
    // one might translate the constructor back to a name.
    if (possibleCtor && possibleCtor.is) {
      newParts[a] = newParts[a] + possibleCtor.is;
      joinIndicies.push(a);
    } else {
      newArgs.push(possibleCtor);
    }
  }

  // This joins where the names were inserted.
  // A possible optimisation here is to incorporate what's in this
  // loop back into the first one to reduce the complexity.
  for (let a = 0; a < joinIndicies.length; a++) {
    const join = joinIndicies[a] - a;
    newParts[join] = newParts[join] + newParts[join + 1];
    newParts.splice(join + 1, 1);
  }

  // Calls out to Lit.
  return html(newParts, ...newArgs);
}

We could also change the marker used when we create the initial HTML string: remove the {{}} in the marker. AFAIK they don't serve a real purpose as we always use the complete marker string in regular expressions. If we then change the _getHtml function to also use the marker instead of nodeMarker if the current string ends with < or </, we'd end up with valid HTML.

The resulting HTML for the template of

html`<${MyComponent} some-attr="${someValue}">${someContent}</${MyComponent}>

would then be

<lit-01234567 some-attr="lit-01234567"><!--lit-01234567--></lit-01234567>

At clone time we need to create the correct element with the correct static attributes, and at update time we need to properly handle changes to the tag as those changes mean we need to create a new element:

  • We have to reparent childnodes
  • We have to set the static attributes again
  • We need to handle node changes in attribute parts.

We'll need to take special care here because changing the node of a part could easily lead to memory leaks, e.g. in the EventPart of lit-extended where listeners won't get removed anymore if the node gets changed.

@treshugart

That's a _really_ interesting snippet. I think it'll have to have it's own caching behavior to only do the setup work once, and it may be helpful to expose the interal litTag function: https://github.com/PolymerLabs/lit-html/blob/master/src/lit-html.ts#L45 which let's you provide your own tempalte cache.

I really like that this could be done on top of lit-html. I'd like to see more opinion and experiments layered this way. It's one reason why I made the lit-html vs lit-extended split - to signal that it's encouraged to make your own variant with different choices.

Would you be interested in experimenting with this in Skate?

If static were a thing, you could even have a small wrapper like this that wraps constructors in ...args with static(tag(Ctor)).

I was thinking that a tag() function would auto-wrap in static() internally, so all a wrapper would have to do is call tag().

I'll bump up the priority of static() since it has yet another use now.

@bgotink I think fixing up tag names at clone time it's going to be expensive and lead to some problem with custom elements reactions. We really want the tree to be as close to it's final state when constructors and connected callback hooks run. We _may_ be able to do the fixup at template prep time, but that still involves more reparenting that it's be good to avoid. If we have the requirement that tag names must be known at template prep time, which seems fine to me, we can do less work.

Would you be interested in experimenting with this in Skate?

I don't see why not. I was hoping to at least put this into the website, but it could be an export from skatejs/renderer-lit-html. Customisation can become a slippery slope, though. We used to have soooo many patches on top of IncrementalDOM that it became not worth it to use it anymore. Have to strike that balance.

I've also been entertaining the idea of your JSX -> Lit transform idea. Essentially, it could just transform from <MyComponent /> to <${MyComponent}></${MyComponent}>. You could go further and lookup the bindings for MyComponent and grab the name from it to get around having to interpolate it, but implementing static makes this simpler.

Customisation can become a slippery slope, though. We used to have soooo many patches on top of IncrementalDOM that it became not worth it to use it anymore. Have to strike that balance.

True, but I'd like to kick off more experimentation outside of lit proper and see what people come up with. lit could be used as a built-your-own-HTML-in-JS-template-system library, rather than the single source of truth on how that should be done. Already someone made an Angular-template flavored version with (foo) and [bar] attribute names. I think it'd be great to see even more opinionated extensions. Ultimately that either lets there be lots of different options, or things could be folded back into lit.

Another thing this idea here highlights is that we really need somewhat a reproducible benchmark setup so we can all have an idea whether a change/wrapper like this hurts perf.

We're dealing with the XY problem here; the core idea of the issue is the fact that we get no warning when <my-custom-component> isn't defined within the scope due to a missing import. Using a constructor as a tag name is just one of the possible solutions, and one that would probably work with most existing tools.

However that's a syntax error, and as such should be dealt with on an IDE / compiler / linter level. Browsers support unknown tag names just fine, to allow async imports and progressive apps, therefore a standalone, runtime-only library can't be a place to deal with such problems.

Maybe a generic web components analyser like Polymer Analyzer? It could be as simple as checking for presence of customElements.define('tag-name', Component) within the imported JavaScript for all custom tags used in a HTML file / template literal.

A solution like @treshugart's wrapper wouldn't be framework-independent - if the imported component doesn't expose the tag name variable, we can't have html`<${static(tagName)}>`.

@HitkoDev I think you misunderstand my intentions. The core of the issue is not definition ordering and delayed upgrades, linting / etc, or the fact that my example utilises a non-standard static property. I'm fairly well versed in the world of web components and understand the intricacies.

What I want is a more explicit, declarative way to use a custom element that solves the common use case. I've been a long-time user of Preact and one of the most useful accessory-features of using JSX to write custom elements is being able to do <MyElement.is /> and not have to ever worry about an element's name within your app. Sure, you need a hardcoded name for deferred upgrades but I've never needed them and I've written hundreds of custom elements. Maybe someday, for sure, but definitely an edge case in the context of pragmatism.

Global names have a long, problematic history. While it's due to the implementation detail of the HTML parser, libraries can provide better ergonomics for this. Opinions about web components from the React camp can be controversial depending on where you sit but Ryan has a great point in this thread. He's not wrong and lays out the obvious prior art here in terms of success: React, and also has some great examples of where it's failed and that we keep coming back to it.

Jason Miller (Preact) and Sean Larkin (Webpack) have had similar ideas in various tweets and gists (that I'm failing to find), that I've shamelessly modified and haphazardly hacked together about using HTML imports for scoping names. Basically:

<import href="./my-element" as="my-element">
<my-element></my-element>

My snippet above, referred to as not being framework independent, is severely hacked together and the concrete usage of is is meant to serve as an example. I raised an issue awhile back about being able to do the reverse of customElements.get().

I really think Lit providing a hook for interpolation prior to invoking the HTML parser would allow this and many other ideas that we haven't been able to think of yet come to fruition.

To your point about linters and such, they could help but they'd suffer from the same amount of inference issues that a runtime library would in that you can't reliably tell if an element will ever eventually be defined. I think this is orthogonal to the discussion, though.

The way DOM works simply doesn't allow elements without unique tag names, and that most certainly won't change. The best we may hope for is the ability to use shadow root as a scope for custom elements (see https://github.com/w3c/webcomponents/issues/716).

The problem with solutions from other frameworks is they all require specific component structure / compilation / virtual DOM / exposed variables / incompatible framework libraries / ..., often making it hard or even impossible to use those components independently. When you're working on a project and don't expect components to be reused outside the project scope, or when you're okay with compilation, there are plenty of options for dealing with this problem. On the other hand, what online community expects is the ability to do this:

<script type="module" src="/node_modules/external_component/ex-component.js"></script>
<ex-component></ex-component>
<script type="text/javascript">
    var exComp = $('ex-component');
    /** 
     * Use some old jQuery code with the component,
     * like binding existing button action to a custom button 
     */
</script>

A pre-parse hook is a good addition to lit-html, and it brings us closer to solving the problem when dealing with internal and framework-specific components, where it's possible to hook into the component registration and obtain or change the tag name.

In case of independent components, we still have the problem of global and scoped tag names, and no way to tell whether a component is already present in the custom element registry. Hacking a way around this shouldn't become a part of lit-html. Instead there should be a proposal to integrate it into the WC API. Maybe something similar to Vue.use(name, component) and new Vue({ components: {...} })?

@justinfagnani so to be clear, I'm a 1000% on board with a static() directive that interpolates prior to parsing. Shall I open a separate issue referencing this one so we can hash it out?

@treshugart Bede filed an issue a while back: https://github.com/PolymerLabs/lit-html/issues/78

It's a pretty simple one to do

Alrighty. Closing in favour of #78 then!

Hey, @justinfagnani, mentioning here as this issue is the most relevant place for it, even if it's closed. @thysultan just mentioned me about unique names in Dio and I wrote up some stuff regarding it in https://github.com/thysultan/dio.js/pull/52#issuecomment-372111041.

Something to point out there, when we were discussing styling and unique names at the web components f2f in Tokyo, is that you most likely don't need to select by tag name. You can probably just add a class to the element and select using that. There's some edge cases to that, but I think most of the time that would work and I just didn't think of it at the time (not sure why).

Mostly just an FYI.

@treshugart Would that eliminate being able to do something like :theme(my-fancy-button) in CSS? (Assumption that :part and :theme are progressing). I do not know how realistic using :theme to style a custom element would be in a shadow DOM world but the use case might be there.

@silenceisgolden not necessarily, because you could use the [hopeful] customElements.getName(Constructor) as detailed in https://github.com/w3c/webcomponents/issues/566 to do something like: :theme(${customElements.getName(Ctor)}). I would think this is the most defensive way to code it anyways, as then you have only one place that hinges on the hardcoded name.

@treshugart That would assume styles are aways in an environment where template literals are available, i.e. a .js/.ts file though I believe. I would hope that the first documented use case for styling with :theme would be :theme(fancy-button) and the backup or framework-specific use case to that would be :theme(${customElements.get(Ctor)}).

@silenceisgolden sure, that's my thoughts, too. My use case for dynamic tag names is an app where you have full control of the components you're using. Using shared custom elements should mean that you also have the opportunity to define them with your own name, also having control. This isn't for the component developer's use case. Component developers should never export a pre-defined custom element, or make assumptions about it's own name.

I have this implemented as a wrapper for lit-html and any other template literal which produces HTML.

https://www.npmjs.com/package/carehtml (Custom Auto Registered Elements HTML)

import { html as litHtml } from 'lit-html';
import takeCareOf from 'carehtml';

const html = takeCareOf(litHtml);

html`<${CustomElement}></${CustomElement}>`

A bit smaller if the tag name is already known.

It has a cache with the original strings array as key so that it only creates one strings array and passes this to lit-html. This needs to be the same reference to keep lit-html from creating the whole template on every call.

Self closing tags could be added as well.

export function tagRef(html) {
  const cache = new WeakMap();
  return (s, ...e) => {
    const tagIndex = (t, i) =>
      // checks for '*<' or '*</' and a valid tagname
      (/[^>]*<\/?$/.test(t) && /[\w-]+/.test(e[i]) && i);

    const indices = s.map(tagIndex).filter((i) => i !== false);
    if (indices.length === 0) return html.call(null, s, ...e);

    const isTagIndex = (i) => indices.indexOf(i) !== -1;

    let strings = cache.get(s);
    if (!strings) {
      strings = s.reduce((acc, token, i) =>
        isTagIndex(i-1) ? acc : // if prev was tag skip token, it was joined below
        isTagIndex(i) ? acc.concat([token, s[i+1]].join(e[i])) :
        acc.concat(token)
      , []);
      cache.set(s, strings);
    }

    const exps = e.filter((_, i) => !isTagIndex(i));
    return html.call(null, strings, ...exps);
  };
}

Test link: https://codesandbox.io/s/6q3q58343
*_edited_

Note that constructs like this disable the ability of lit-html to effectively cache your templates, which means that on every re-render, it will destroy the DOM and rebuild it from template. Dynamic tags are not supported by lit-html for this reason.

Just leaving this warning here since people seem to keep finding this thread. I strongly recommend NOT to do anything like this, unless you have a VERY good reason to do so. Your rendering performance will degrade significantly when you do this.

@ruphin as far as I understand it it all depends on the strings argument of the template function. If this is the same reference (not a newly created array) then lit-html should be able to use its cache.

html.call(null, strings, ...exps)

In the above you'll have to make sure that strings is the same reference on subsequent calls. One easy way to do this is by using a WeakMap and set the key to the original strings array and the value to the newly create strings array and use that as a cache...

Yes, it is possible to a degree, but this requires a specific implementation that none of the above examples include.

It also means that when the dynamic tag changes, the entire template is re-rendered, which is not what developers expect coming from React or similar environments. This is why I think it is a bad idea to promote this pattern in general, because it breaks expectations of what lit-html does.

Experienced developers with very specific use cases may find a purpose for this, but for general public this pattern should not be promoted in any way.

@ruphin I agree that current implementations including mine in carehtml are naive, my bad. But this is not impossible as @luwes pointed out above. I already made a few local tests proving that runtime performance will not decrease significantly when using a cache like explained above (still need to publish an update with tests somewhere), so there will be at least a choice for developers if they want this tradeoff between flexibility and performance.

Also for even better performance it will be possible to transpile code for production to fully remove runtime costs (in a similar fashion to awesome htm by @developit who made use of babel for that here babel-plugin-htm). I'm gonna investigate this as well. This will be optional of course.

It also means that when the dynamic tag changes, the entire template is re-rendered, which is not what developers expect coming from React or similar environments.

Can you please elaborate on that?

For the note, in carehtml I was thinking a lot about the need to reuse existing registered names for encountered classes (even if they were register not by carehtml itself, but by other people using custom elements registry directly) to not double register them and hence change the name. This is possible and is partially implemented there already. Probably still needs a bit of rework, but conceptually I don't see any gotchas to not offer it to general public.

The reason LitHTML is fast is because it uses mostly native capabilities to do rendering, and does not have to build virtual trees. However, there is no Element.changeTag()-like API in the platform. If you want to change a node type, you have to re-render that node and all it's content. Even the most advanced implementation using some form of templateString-caching as suggested by @luwes is indistinguishable performance-wise from switching between different static templates (when the dynamic tag changes).

VirtualDOM lends itself to this type of rendering, and if you wish to use dynamic tags, you will probably get more efficiency out of VirtualDOM rendering techniques.

If you want to get that same level of efficiency with LitHTML, you will have to implement a more complex re-parenting scheme as described higher up in the thread, at which point you are essentially re-implementing functionality from VirtualDOM-like renderers. It is not technically impossible, but implementing something like that is way beyond the capabilities of most users, and far more advanced than the solutions suggested in this thread.

As an aside, the performance cost of naive implementations right now is probably not very high, but this is because of a bug in Safari that causes the object ID of StringsArrays to occasionally change. To solve this we have a fallback key mechanism that checks for string equality, which means that naive implementations get "caching" for free right now (the key comparison/lookup is still strictly slower). Once Safari has been fixed and the workaround is removed from LitHTML, these implementations will suddenly stop working and lose all caching capabilities, which means they will fully re-build the templates and re-render the DOM on every render call, even if the tag stays the same.

Even when some kind of cache is implemented correctly (which is not trivial), changing the value of a tag will still cause all the nodes in the template to re-render, including the static ones, which breaks user expectation. This breaks all templates with input elements in their static content. Right now this is safe because regardless of dynamic values inserted by LitHTML, the static parts of the template are unchanged. If you have a dynamic tag anywhere inside the template, all nodes will be destroyed and recreated when the dynamic tag changes, which destroys all state of the input elements (like the value, or the fact that they may currently be the active/selected element).

These are all implementation details which normal users are not expected to be aware of or understand. This is why I think it is important that average users don't get the idea that using dynamic tags is "fine" or even a consideration. The risk is average users googling how to use dynamic tags, landing on a thread like this with naive implementations that seem to solve their problem, and them using it without understanding the implications. There are other solutions than dynamic tags to solve the problems that users have, and they should look into those instead.

Good points! It should definitely be used with caution and probably good to keep out of lit-html core, though I do still see merit to have these kind of pre-transform utilities.

Also I think most of the people like @bashmish on this thread were not looking for "dynamic" tags that could change in every render (going from a <b> tag to <i> tag and back again), rather a one off pre-compile step in which after the template strings passed to lit are set in stone.

To that point I think people coming from React have the concept of defining an exportable component as a class or function and this is used in the template of another component in another file. You should see it more as a reference or an alias, not a variable that changes at runtime.

Would love to see a pug-lit-html 😄

Very nice explanation of the idea on the conceptual level @luwes 👍

On the implementation level carehtml ignores any other types besides Custom Element classes and just passes them directly to lit-html, while for encountered classes it registers or reuses previously registered tag names, keeping them static. So there is no "dynamic" tag change in the implementation as well, and even more importantly there is no support for a value containing a tag name in a string.

import { html } from 'lit-html';
import takeCareOf from 'carehtml';

// works in carehtml
html`<${MyCustomElement}></${MyCustomElement}>`

// DOES NOT work
html`<${'tag-name'}></${'tag-name'}>`

Btw this also means that carehtml DOES NOT add a security hole for XSS attacks and hence does not require any unsafeSmth helper.

As an aside, the performance cost of naive implementations right now is probably not very high, but this is because of a bug in Safari that causes the object ID of StringsArrays to occasionally change. To solve this we have a fallback key mechanism that checks for string equality, which means that naive implementations get "caching" for free right now (the key comparison/lookup is still strictly slower).

The cache I'm working on has exactly the same string references as an output, because it implements similar algorithm that lit-html has for Safari internally. Let me finish my work and publish it, then you can judge a non-naive implementation.

Hi, in our team we have solution like carehtml, but with important additional point: we caching templates by TemplateStringsArray.

https://gist.github.com/AStaroverov/56448f9baa560b4b7489ecf8ca0c36c8

for anyone interested, here's an update to @AStaroverov's gist with better caching, it makes sure that the tag names are also the same.

https://gist.github.com/darionco/823817008596bb7a518821e7b8201478

A bit late to the party... I just released some of my private helpers for working with scoped registries (it has also a version of the gist from @darionco which will define the custom element if it's not already defined or just use the tag under which the element is defined)
furthermore the lib has a custom template factory to deal with scoped custom elements in the lit-html render function (no need to decorate/replace lits' html) (see README)
https://www.npmjs.com/package/lit-html-scoped-registry-helper

Was this page helpful?
0 / 5 - 0 ratings

Related issues

depeele picture depeele  Â·  3Comments

justinfagnani picture justinfagnani  Â·  4Comments

AndyOGo picture AndyOGo  Â·  3Comments

justinfagnani picture justinfagnani  Â·  3Comments

valdrinkoshi picture valdrinkoshi  Â·  5Comments