mirror of
https://github.com/gapmiss/iconoir-icons.git
synced 2026-07-22 08:00:25 +00:00
182 lines
5.7 KiB
TypeScript
182 lines
5.7 KiB
TypeScript
import { Plugin, TFile,
|
|
Editor, EditorPosition,
|
|
EditorSuggestTriggerInfo,
|
|
EditorSuggest, EditorSuggestContext,
|
|
MarkdownPostProcessor } from 'obsidian';
|
|
import {html, LitElement} from 'lit';
|
|
import { iconoir } from './iconoirNames';
|
|
|
|
enum ComponentChoice {
|
|
Default = "Default",
|
|
}
|
|
|
|
export default class IconoirPlugin extends Plugin {
|
|
iconoirNames: string[];
|
|
isListItem: any;
|
|
|
|
async litBlockHandler(type: ComponentChoice, source: string, el: HTMLElement, ctx: any): Promise<any> {
|
|
const element:any = document.createRange().createContextualFragment(source);
|
|
let input = element
|
|
const blk = el.createEl("div", {cls: "lit-block"});
|
|
let inputElement: HTMLElement;
|
|
inputElement = blk.createEl("div", {text: input, cls: "lit-innerblock"});
|
|
}
|
|
|
|
async onload() {
|
|
this.registerEditorSuggest(new IconoirSuggester(this));
|
|
this.registerMarkdownCodeBlockProcessor("iconoir", this.litBlockHandler.bind(this, null));
|
|
this.registerMarkdownPostProcessor(buildPostProcessor());
|
|
this.iconoirNames = Object.keys(iconoir);
|
|
this.isListItem = false;
|
|
console.log('iconoir-icons loaded');
|
|
}
|
|
onunload() {
|
|
console.log('iconoir-icons unloaded');
|
|
}
|
|
}
|
|
|
|
export function buildPostProcessor(): MarkdownPostProcessor {
|
|
return (el) => {
|
|
el.findAll("code").forEach((code) => {
|
|
let text = code.innerText.trim();
|
|
console.log(text);
|
|
if (text.startsWith('~![')) {
|
|
let frag = text.substring(2).trim();
|
|
if (frag.endsWith(']')) {
|
|
let content = frag.substring(frag.length-1,1).trim();
|
|
const arr = (code.parentElement?.tagName === 'TD' || code.parentElement?.tagName === 'TH')
|
|
? content.split('\\|')
|
|
: content.split('|');
|
|
if (arr[0] === '' || arr[0] === undefined) {
|
|
return '';
|
|
}
|
|
if (code.parentElement?.tagName === 'LI') {
|
|
code.parentElement?.addClass('special-iconoir-list-callout');
|
|
code.parentElement?.setAttr("data-icon", arr[0]);
|
|
}
|
|
if (code.parentElement?.tagName === 'TH') {
|
|
code.parentElement?.addClass('special-iconoir-th-callout');
|
|
code.parentElement?.setAttr("data-icon", arr[0]);
|
|
}
|
|
if (code.parentElement?.tagName === 'TD') {
|
|
code.parentElement?.addClass('special-iconoir-td-callout');
|
|
code.parentElement?.setAttr("data-icon", arr[0]);
|
|
}
|
|
var newEl = document.createElement("iconoir-icon");
|
|
newEl.setAttribute('name',arr[0]);
|
|
newEl.setAttribute('aria-label',arr[0]+' icon');
|
|
newEl.setAttribute('aria-label-position', 'top');
|
|
if (arr[1] !== undefined) {
|
|
newEl.setAttribute('stroke',arr[1]);
|
|
}
|
|
if (arr[2] !== undefined) {
|
|
newEl.setAttribute('width',arr[2]);
|
|
}
|
|
if (arr[3] !== undefined) {
|
|
newEl.setAttribute('height',arr[3]);
|
|
}
|
|
if (arr[4] !== undefined) {
|
|
newEl.setAttribute('style',arr[4]);
|
|
}
|
|
code.parentNode?.replaceChild(newEl, code);
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
class IconoirSuggester extends EditorSuggest<string> {
|
|
plugin: IconoirPlugin;
|
|
|
|
constructor(plugin: IconoirPlugin) {
|
|
super(plugin.app);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
onTrigger(cursor: EditorPosition, editor: Editor, _: TFile): EditorSuggestTriggerInfo | null {
|
|
let foo='bar';
|
|
if (foo==='bar') {
|
|
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
|
|
const match = sub.match(/&&\S+$/)?.first();
|
|
if (match) {
|
|
return {
|
|
end: cursor,
|
|
start: {
|
|
ch: sub.lastIndexOf(match),
|
|
line: cursor.line,
|
|
},
|
|
query: match,
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getSuggestions(context: EditorSuggestContext): string[] {
|
|
let iconoir_query = context.query.replace('&&', '').toLowerCase();
|
|
return this.plugin.iconoirNames.filter(p => p.includes(iconoir_query));
|
|
}
|
|
|
|
renderSuggestion(suggestion: string, el: HTMLElement): void {
|
|
const outer = el.createDiv({ cls: "icon-suggester-container" });
|
|
outer.createDiv({ cls: "iconoir-icon-name" }).setText(suggestion);
|
|
}
|
|
|
|
selectSuggestion(suggestion: string): void {
|
|
if(this.context) {
|
|
// (this.context.editor as Editor).replaceRange('`~!['+iconoir[suggestion]+'|currentColor]`', this.context.start, this.context.end);
|
|
(this.context.editor as Editor).replaceRange('`~!['+iconoir[suggestion]+']`', this.context.start, this.context.end);
|
|
}
|
|
}
|
|
}
|
|
|
|
class IconoirIcon extends LitElement {
|
|
static get properties() {
|
|
return {
|
|
name: { type: String },
|
|
stroke: { type: String },
|
|
width: { type: String },
|
|
height: { type: String },
|
|
css: { type: String }
|
|
}
|
|
}
|
|
constructor() {
|
|
super();
|
|
this.name = 'iconoir-1st-medal';
|
|
this.stroke = 'currentColor';
|
|
this.width = '1.2em';
|
|
this.height = '1.2em';
|
|
this.css = '';
|
|
}
|
|
render() {
|
|
return html`
|
|
<i class="${this.name}" style="${this.css}"></i>
|
|
<style>
|
|
i[class^="iconoir-"]::before,
|
|
i[class*=" iconoir-"]::before {
|
|
content: " ";
|
|
display: var(--special-display);
|
|
-webkit-mask-image:var(--${this.name});
|
|
mask-image:var(--${this.name});
|
|
background: ${this.stroke};
|
|
mask-size: cover;
|
|
-webkit-mask-size: cover;
|
|
width: ${this.width};
|
|
height: ${this.height};
|
|
}
|
|
i[class^="iconoir-"],
|
|
i[class*=" iconoir-"] {
|
|
display:inline-flex !important;
|
|
border: var(--special-border);
|
|
margin: var(--special-margin);
|
|
padding: var(--special-padding);
|
|
}
|
|
</style>
|
|
`;
|
|
}
|
|
}
|
|
|
|
var isRegistered = window.customElements.get('iconoir-icon');
|
|
if (isRegistered === undefined) {
|
|
window.customElements.define('iconoir-icon', IconoirIcon);
|
|
}
|