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

Replace sign_in.js by webcomponent #4023

Merged
merged 14 commits into from
Oct 5, 2022
14 changes: 11 additions & 3 deletions app/assets/javascripts/components/datalist_input.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { customElement, property } from "lit/decorators.js";
import { html, TemplateResult } from "lit";
import { DirectiveParent, html, TemplateResult } from "lit";
import { ShadowlessLitElement } from "components/shadowless_lit_element";
import { ref, Ref, createRef } from "lit/directives/ref.js";
import { watchMixin } from "components/watch_mixin";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { htmlEncode } from "util";

export type Option = {label: string, value: string, extra?: string};

Expand Down Expand Up @@ -123,6 +125,12 @@ export class DatalistInput extends watchMixin(ShadowlessLitElement) {
}
}

mark(s: string): TemplateResult {
return this.filter ?
html`${unsafeHTML(htmlEncode(s).replace(new RegExp(this.filter, "gi"), m => `<b>${m}</b>`))}` :
html`${s}`;
}

render(): TemplateResult {
return html`
<div class="dropdown">
Expand All @@ -138,9 +146,9 @@ export class DatalistInput extends watchMixin(ShadowlessLitElement) {
style="position: fixed; top: ${this.dropdown_top}px; left: ${this.dropdown_left}px; max-width: ${this.dropdown_width}px; overflow-x: hidden;">
${this.filtered_options.map(option => html`
<li><a class="dropdown-item ${this.value === option.value ? "active" :""} " @click=${ e => this.select(option, e)} style="cursor: pointer;">
${option.label}
${this.mark(option.label)}
${option.extra ? html`
<br/><span class="small">${option.extra}</span>
<br/><span class="small">${this.mark(option.extra)}</span>
`:""}
</a></li>
`)}
Expand Down
8 changes: 8 additions & 0 deletions app/assets/javascripts/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ const ready = new Promise(resolve => {
}
});

function htmlEncode(str) {
return String(str)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit hesitant about adding this function because it's incomplete. (and in combination with the unsafeHTML function where it's called). Is there an alternative?

Copy link
Contributor Author

@jorg-vr jorg-vr Oct 5, 2022

Choose a reason for hiding this comment

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

I don't see a way without the unsafe html that also marks the search results. And as the institution names are user input we need some kind of html encoding.

This method is an often suggested solution:

Some indeed change more keys. I will add those. They are more relevant when the string is used within html tags. But for a general util method it should cover all cases.

There is weirdly no standard javascript method for this. JQuery and lodash provide solutions, but we dont want to include those.

This might be a better alternative:

  var text = document.createTextNode(html);
  var p = document.createElement('p');
  p.appendChild(text);
  return p.innerHTML;
}```

Copy link
Member

Choose a reason for hiding this comment

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


export {
createDelayer,
Expand All @@ -192,4 +199,5 @@ export {
setDocumentTitle,
initDatePicker,
ready,
htmlEncode,
};