Skip to content

Commit

Permalink
Merge pull request #1867 from googlefonts/issue-1856-refactor-GlyphsS…
Browse files Browse the repository at this point in the history
…earch

Refactor GlyphsSearch
  • Loading branch information
justvanrossum authored Dec 18, 2024
2 parents 8fabc91 + 8eff649 commit 02974ab
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { themeColorCSS } from "./theme-support.js";
import { UIList } from "./ui-list.js";
import * as html from "/core/html-utils.js";
import { UnlitElement } from "/core/html-utils.js";
import { translate } from "/core/localization.js";
import {
getCharFromCodePoint,
guessCharFromGlyphName,
makeUPlusStringFromCodePoint,
} from "/core/utils.js";

const colors = {
"search-input-foreground-color": ["black", "white"],
"search-input-background-color": ["#eee", "#333"],
};

export class GlyphsSearch extends UnlitElement {
export class GlyphsSearchField extends UnlitElement {
static styles = `
${themeColorCSS(colors)}
Expand Down Expand Up @@ -43,60 +37,17 @@ export class GlyphsSearch extends UnlitElement {
}
`;

constructor() {
constructor(glyphsListItemsController, controllerKey) {
super();

this.glyphsListItemsController = glyphsListItemsController;
this.controllerKey = controllerKey;
this.searchField = html.input({
type: "text",
placeholder: translate("sidebar.glyphs.search"),
autocomplete: "off",
oninput: (event) => this._searchFieldChanged(event),
});

const columnDescriptions = [
{
key: "char",
title: " ",
width: "1.8em",
cellFactory: (item, description) => {
if (item.unicodes[0]) {
return getCharFromCodePoint(item.unicodes[0]);
}
const guessedChar = guessCharFromGlyphName(item.glyphName);
return guessedChar ? html.span({ class: "guessed-char" }, [guessedChar]) : "";
},
},
{ key: "glyphName", title: "glyph name", width: "10em", isIdentifierKey: true },
{
key: "unicode",
width: "fit-content",
get: (item) => item.unicodes.map(makeUPlusStringFromCodePoint).join(","),
},
];
this.glyphNamesList = new UIList();
this.glyphNamesList.appendStyle(`
.guessed-char {
color: #999;
}
`);
this.glyphNamesList.columnDescriptions = columnDescriptions;

this.glyphNamesList.addEventListener("listSelectionChanged", () => {
const event = new CustomEvent("selectedGlyphNameChanged", {
bubbles: false,
detail: this.getSelectedGlyphName(),
});
this.dispatchEvent(event);
});

this.glyphNamesList.addEventListener("rowDoubleClicked", () => {
const event = new CustomEvent("selectedGlyphNameDoubleClicked", {
bubbles: false,
detail: this.getSelectedGlyphName(),
});
this.dispatchEvent(event);
});

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

this.glyphMap = {};
Expand All @@ -107,7 +58,7 @@ export class GlyphsSearch extends UnlitElement {
}

render() {
return [this.searchField, this.glyphNamesList];
return this.searchField;
}

get glyphMap() {
Expand All @@ -119,14 +70,6 @@ export class GlyphsSearch extends UnlitElement {
this.updateGlyphNamesListContent();
}

getSelectedGlyphName() {
return this.glyphNamesList.items[this.glyphNamesList.selectedItemIndex]?.glyphName;
}

getFilteredGlyphNames() {
return this.glyphNamesList.items.map((item) => item.glyphName);
}

updateGlyphNamesListContent() {
const glyphMap = this.glyphMap;
this.glyphsListItems = [];
Expand Down Expand Up @@ -155,11 +98,11 @@ export class GlyphsSearch extends UnlitElement {
const filteredGlyphItems = this.glyphsListItems.filter(
this._glyphNamesListFilterFunc
);
this.glyphNamesList.setItems(filteredGlyphItems);
this.glyphsListItemsController.model[this.controllerKey] = filteredGlyphItems;
}
}

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

function glyphItemSortFunc(item1, item2) {
const uniCmp = compare(item1.unicodes[0], item2.unicodes[0]);
Expand Down
109 changes: 109 additions & 0 deletions src/fontra/client/web-components/glyphs-search-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { GlyphsSearchField } from "./glyphs-search-field.js";
import { UIList } from "./ui-list.js";
import * as html from "/core/html-utils.js";
import { UnlitElement } from "/core/html-utils.js";
import { ObservableController } from "/core/observable-object.js";
import {
getCharFromCodePoint,
guessCharFromGlyphName,
makeUPlusStringFromCodePoint,
throttleCalls,
} from "/core/utils.js";

export class GlyphsSearchList extends UnlitElement {
constructor() {
super();
this.glyphsListItemsController = new ObservableController({
glyphsListItems: [],
});

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

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

makeGlyphNamesList() {
const columnDescriptions = [
{
key: "char",
title: " ",
width: "1.8em",
cellFactory: (item, description) => {
if (item.unicodes[0]) {
return getCharFromCodePoint(item.unicodes[0]);
}
const guessedChar = guessCharFromGlyphName(item.glyphName);
return guessedChar ? html.span({ class: "guessed-char" }, [guessedChar]) : "";
},
},
{ key: "glyphName", title: "glyph name", width: "10em", isIdentifierKey: true },
{
key: "unicode",
width: "fit-content",
get: (item) => item.unicodes.map(makeUPlusStringFromCodePoint).join(","),
},
];
const glyphNamesList = new UIList();
glyphNamesList.appendStyle(`
.guessed-char {
color: #999;
}
`);
glyphNamesList.columnDescriptions = columnDescriptions;

glyphNamesList.addEventListener("listSelectionChanged", () => {
const event = new CustomEvent("selectedGlyphNameChanged", {
bubbles: false,
detail: this.getSelectedGlyphName(),
});
this.dispatchEvent(event);
});

glyphNamesList.addEventListener("rowDoubleClicked", () => {
const event = new CustomEvent("selectedGlyphNameDoubleClicked", {
bubbles: false,
detail: this.getSelectedGlyphName(),
});
this.dispatchEvent(event);
});
return glyphNamesList;
}

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

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

async render() {
this.glyphsListItemsController.addKeyListener(
"glyphsListItems",
this.throttledUpdate
);
return [this.searchField, this.glyphNamesList];
}

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

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

getSelectedGlyphName() {
return this.glyphNamesList.items[this.glyphNamesList.selectedItemIndex]?.glyphName;
}

getFilteredGlyphNames() {
return this.glyphNamesList.items.map((item) => item.glyphName);
}
}

customElements.define("glyphs-search-list", GlyphsSearchList);
2 changes: 1 addition & 1 deletion src/fontra/views/editor/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<script type="module" src="/core/theme-settings.js"></script>
<script type="module" src="/web-components/add-remove-buttons.js"></script>
<script type="module" src="/web-components/designspace-location.js"></script>
<script type="module" src="/web-components/glyphs-search.js"></script>
<script type="module" src="/web-components/glyphs-search-list.js"></script>
<script type="module" src="/web-components/grouped-settings.js"></script>
<script type="module" src="/web-components/inline-svg.js"></script>
<script type="module" src="/web-components/modal-dialog.js"></script>
Expand Down
4 changes: 2 additions & 2 deletions src/fontra/views/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3148,7 +3148,7 @@ export class EditorController {
usedBy.map((glyphName) => [glyphName, this.fontController.glyphMap[glyphName]])
);

const glyphsSearch = document.createElement("glyphs-search");
const glyphsSearch = document.createElement("glyphs-search-list");
glyphsSearch.glyphMap = glyphMap;

glyphsSearch.addEventListener("selectedGlyphNameDoubleClicked", (event) => {
Expand Down Expand Up @@ -3223,7 +3223,7 @@ export class EditorController {
titleLabel = translate("dialog.glyphs.search"),
okLabel = translate("dialog.add")
) {
const glyphsSearch = document.createElement("glyphs-search");
const glyphsSearch = document.createElement("glyphs-search-list");
glyphsSearch.glyphMap = this.fontController.glyphMap;

glyphsSearch.addEventListener("selectedGlyphNameChanged", (event) => {
Expand Down
8 changes: 4 additions & 4 deletions src/fontra/views/editor/panel-glyph-search.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class GlyphSearchPanel extends Panel {

constructor(editorController) {
super(editorController);
this.glyphsSearch = this.contentElement.querySelector("#glyphs-search");
this.glyphsSearch = this.contentElement.querySelector("#glyphs-search-list");
this.glyphsSearch.addEventListener("selectedGlyphNameChanged", (event) =>
this.glyphNameChangedCallback(event.detail)
);
Expand Down Expand Up @@ -65,16 +65,16 @@ export default class GlyphSearchPanel extends Panel {
class: "glyph-search",
},
[
html.createDomElement("glyphs-search", {
id: "glyphs-search",
html.createDomElement("glyphs-search-list", {
id: "glyphs-search-list",
}),
]
);
}

async toggle(on, focus) {
if (on && focus) {
const glyphsSearch = this.contentElement.querySelector("#glyphs-search");
const glyphsSearch = this.contentElement.querySelector("#glyphs-search-list");
glyphsSearch.focusSearchField();
}
}
Expand Down

0 comments on commit 02974ab

Please sign in to comment.