Skip to content

Commit

Permalink
Merge pull request #1885 from googlefonts/glyphs-search-refactor-2
Browse files Browse the repository at this point in the history
Glyphs search refactor 2
  • Loading branch information
justvanrossum authored Dec 22, 2024
2 parents aa53e90 + e6eb6ab commit 61a7436
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 63 deletions.
59 changes: 18 additions & 41 deletions src/fontra/client/web-components/glyphs-search-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ export class GlyphsSearchField extends SimpleElement {
}
`;

constructor(glyphsListItemsController, controllerKey) {
constructor() {
super();
this.glyphsListItemsController = glyphsListItemsController;
this.controllerKey = controllerKey;
this.searchField = html.input({
type: "text",
placeholder: translate("sidebar.glyphs.search"),
Expand All @@ -41,37 +39,13 @@ export class GlyphsSearchField extends SimpleElement {

this._glyphNamesListFilterFunc = (item) => true; // pass all through

this.glyphMap = {};

this.shadowRoot.appendChild(this.searchField);
}

focusSearchField() {
this.searchField.focus();
}

get glyphMap() {
return this._glyphMap;
}

set glyphMap(glyphMap) {
this._glyphMap = glyphMap;
this.updateGlyphNamesListContent();
}

updateGlyphNamesListContent() {
const glyphMap = this.glyphMap;
this.glyphsListItems = [];
for (const glyphName in glyphMap) {
this.glyphsListItems.push({
glyphName: glyphName,
unicodes: glyphMap[glyphName],
});
}
this.glyphsListItems.sort(glyphItemSortFunc);
this._setFilteredGlyphNamesListContent();
}

_searchFieldChanged(event) {
const value = event.target.value;
const searchItems = value.split(/\s+/).filter((item) => item.length);
Expand All @@ -80,25 +54,22 @@ export class GlyphsSearchField extends SimpleElement {
.map((item) => item.codePointAt(0).toString(16).toUpperCase().padStart(4, "0"));
searchItems.push(...hexSearchItems);
this._glyphNamesListFilterFunc = (item) => glyphFilterFunc(item, searchItems);
this._setFilteredGlyphNamesListContent();
this.oninput?.(event);
}

sortGlyphs(glyphs) {
glyphs = [...glyphs];
glyphs.sort(glyphItemSortFunc);
return glyphs;
}

_setFilteredGlyphNamesListContent() {
const filteredGlyphItems = this.glyphsListItems.filter(
this._glyphNamesListFilterFunc
);
this.glyphsListItemsController.model[this.controllerKey] = filteredGlyphItems;
filterGlyphs(glyphs) {
return glyphs.filter(this._glyphNamesListFilterFunc);
}
}

customElements.define("glyphs-search-field", GlyphsSearchField);

function glyphItemSortFunc(item1, item2) {
const uniCmp = compare(item1.unicodes[0], item2.unicodes[0]);
const glyphNameCmp = compare(item1.glyphName, item2.glyphName);
return uniCmp ? uniCmp : glyphNameCmp;
}

function glyphFilterFunc(item, searchItems) {
if (!searchItems.length) {
return true;
Expand All @@ -107,8 +78,8 @@ function glyphFilterFunc(item, searchItems) {
if (item.glyphName.indexOf(searchString) >= 0) {
return true;
}
if (item.unicodes[0] !== undefined) {
const char = String.fromCodePoint(item.unicodes[0]);
if (item.codePoints[0] !== undefined) {
const char = String.fromCodePoint(item.codePoints[0]);
if (searchString === char) {
return true;
}
Expand All @@ -117,6 +88,12 @@ function glyphFilterFunc(item, searchItems) {
return false;
}

function glyphItemSortFunc(item1, item2) {
const uniCmp = compare(item1.codePoints[0], item2.codePoints[0]);
const glyphNameCmp = compare(item1.glyphName, item2.glyphName);
return uniCmp ? uniCmp : glyphNameCmp;
}

function compare(a, b) {
// sort undefined at the end
if (a === b) {
Expand Down
50 changes: 28 additions & 22 deletions src/fontra/client/web-components/glyphs-search-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { GlyphsSearchField } from "./glyphs-search-field.js";
import { UIList } from "./ui-list.js";
import * as html from "/core/html-utils.js";
import { SimpleElement } from "/core/html-utils.js";
import { ObservableController } from "/core/observable-object.js";
import {
getCharFromCodePoint,
guessCharFromGlyphName,
Expand All @@ -24,36 +23,27 @@ export class GlyphsSearchList extends SimpleElement {

constructor() {
super();
this.glyphsListItemsController = new ObservableController({
glyphsListItems: [],
});

this.searchField = new GlyphsSearchField(
this.glyphsListItemsController,
"glyphsListItems"
);
this.glyphNamesList = this.makeGlyphNamesList();
this.searchField = new GlyphsSearchField();
this.glyphNamesList = this._makeGlyphNamesList();

this.throttledUpdate = throttleCalls(() => this.update(), 50);

this.glyphsListItemsController.addKeyListener(
"glyphsListItems",
this.throttledUpdate
);
this.searchField.oninput = (event) => this.throttledUpdate();

this.shadowRoot.appendChild(this.searchField);
this.shadowRoot.appendChild(this.glyphNamesList);
}

makeGlyphNamesList() {
_makeGlyphNamesList() {
const columnDescriptions = [
{
key: "char",
title: " ",
width: "1.8em",
cellFactory: (item, description) => {
if (item.unicodes[0]) {
return getCharFromCodePoint(item.unicodes[0]);
if (item.codePoints[0]) {
return getCharFromCodePoint(item.codePoints[0]);
}
const guessedChar = guessCharFromGlyphName(item.glyphName);
return guessedChar ? html.span({ class: "guessed-char" }, [guessedChar]) : "";
Expand All @@ -63,7 +53,7 @@ export class GlyphsSearchList extends SimpleElement {
{
key: "unicode",
width: "fit-content",
get: (item) => item.unicodes.map(makeUPlusStringFromCodePoint).join(","),
get: (item) => item.codePoints.map(makeUPlusStringFromCodePoint).join(","),
},
];
const glyphNamesList = new UIList();
Expand Down Expand Up @@ -96,20 +86,36 @@ export class GlyphsSearchList extends SimpleElement {
this.searchField.focusSearchField();
}

async update() {
this.glyphNamesList.setItems(this.glyphsListItemsController.model.glyphsListItems);
update() {
this.updateGlyphNamesListContent();
}

get glyphMap() {
return this.searchField._glyphMap;
return this._glyphMap;
}

set glyphMap(glyphMap) {
this.searchField.glyphMap = glyphMap;
this._glyphMap = glyphMap;
this.updateGlyphNamesListContent();
}

updateGlyphNamesListContent() {
this.searchField.updateGlyphNamesListContent();
const glyphMap = this.glyphMap;
const glyphsListItems = [];
for (const glyphName in glyphMap) {
glyphsListItems.push({
glyphName: glyphName,
codePoints: glyphMap[glyphName],
});
}

this.glyphsListItems = this.searchField.sortGlyphs(glyphsListItems);
this._setFilteredGlyphNamesListContent();
}

_setFilteredGlyphNamesListContent() {
const filteredGlyphItems = this.searchField.filterGlyphs(this.glyphsListItems);
this.glyphNamesList.setItems(filteredGlyphItems);
}

getSelectedGlyphName() {
Expand Down

0 comments on commit 61a7436

Please sign in to comment.