Skip to content

Commit

Permalink
plugin_browserに型定義を追加
Browse files Browse the repository at this point in the history
  • Loading branch information
kujirahand committed Oct 18, 2024
1 parent 704a095 commit 33af9cb
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 115 deletions.
25 changes: 13 additions & 12 deletions core/src/plugin_api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@
* @fileOverview プラグインAPIの型定義
*/

export type NakoVariables = Map<string, any>;
export type NakoCallbackEvent = (e: any)=>any;
export type NakoVariables = Map<string, unknown>;
export type NakoCallbackEvent = ((e: object) => boolean) | ((e: object, sys: any) => boolean);
export type NakoCallback = string | NakoCallbackEvent;
export type NakoValue = string | number | boolean | bigint | object | null | undefined;

// NakoSystem
export interface NakoSystem {
version: string;
coreVersion: string;
isDebug: boolean;
tags: any; // 何を設定しても良い自由なタグ領域
__interval: any[]; // setIntervalのIDを保持する配列
__timeout: any[]; // setTimeoutのIDを保持する配列
__interval: string|number[]; // setIntervalのIDを保持する配列
__timeout: string|number[]; // setTimeoutのIDを保持する配列
__reisetu: number; // 礼節レベル(ジョーク機能)
__printPool: string; // 『継続表示』のための一時変数(『表示』実行で初期化)
__getSysVar (name: string, defaultValue?: any): any; // システム変数の参照
__setSysVar (name: string, value: any): void; // システム変数の設定
__findVar (name: NakoCallback, defaultValue?: any): any;
__findFunc (nameStr: any, parentFunc: string): any;
__exec (func: string, params: any[]): any;
__getSysVar(name: string, defaultValue?: NakoValue): any; // システム変数の参照
__setSysVar(name: string, value: NakoValue): void; // システム変数の設定
__findVar(name: NakoCallback, defaultValue?: NakoValue): any; // 変数を探す
__findFunc(nameStr: string, parentFunc: string): NakoCallback | any;
__exec(func: string, params: NakoValue[]): any;
__setSore(v: any): void;
__getSore(): any;
__loadScript(url: string): Promise<void>; // JSのスクリプトを読み込む (ex) グラフ描画(plguin_browser_chart.mts)
Expand All @@ -32,9 +33,9 @@ export interface NakoSystem {
__formatDate (t: Date): string;
__formatTime (t: Date): string;
__str2date(s: string): Date;
__parseFloatOrBigint(v: any): number | bigint;
__evalJS(code: string, sys?: NakoSystem): any;
__evalSafe(code: string): any;
__parseFloatOrBigint(v: NakoValue): number | bigint;
__evalJS(code: string, sys?: NakoSystem): NakoValue;
__evalSafe(code: string): NakoValue;
josiList: string[];
reservedWords: string[];
// 実際には存在するが利用が非推奨なメソッドやプロパティ
Expand Down
2 changes: 1 addition & 1 deletion src/cnako3.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CNako3 } from './cnako3mod.mjs'
const cnako3: CNako3 = new CNako3()
try {
await cnako3.execCommand()
} catch (err: any) {
} catch (err: unknown) {
// 何かしらのエラーがあればコンソールに返す
// ここで出るエラーは致命的なエラー
console.error('[cnako3のエラー]', err)
Expand Down
132 changes: 78 additions & 54 deletions src/plugin_browser.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// plugin_browser
// @ts-nocheck
/**
* @fileOverview ブラウザプラグイン
*/
import { NakoValue, NakoCallback, NakoCallbackEvent } from '../core/src/plugin_api.mjs'
import { NakoBrowsesrSystem, IBrowserDocument, IBrowserWindow, IBrowserLocation } from './plugin_browser_api.mjs'

import PartBrowserColor from './plugin_browser_color.mjs'
import PartBrowserSystem from './plugin_browser_system.mjs'
import PartBrowserDialog from './plugin_browser_dialog.mjs'
Expand Down Expand Up @@ -55,20 +59,20 @@ const PluginBrowser = {
type: 'func',
josi: [],
pure: true,
fn: function (sys: any) {
fn: function (sys: NakoBrowsesrSystem) {
/* eslint no-global-assign: 0 */
const doc: any = (typeof document === 'undefined') ? { 'body': {} } : document
const win: any = (typeof window === 'undefined') ? { 'location': { 'href': 'http://localhost/' } } : window
const nav: any = (typeof navigator === 'undefined') ? {} : navigator
const loc: any = (typeof win.location === 'undefined') ? { 'href': 'http://localhost/' } : win.location
const doc: IBrowserDocument = (typeof document === 'undefined') ? { 'body': {}, 'querySelector': ()=>null } : document
const win: IBrowserWindow = (typeof window === 'undefined') ? { 'location': { 'href': 'http://localhost/' } } : window
const nav: object = (typeof navigator === 'undefined') ? {} : navigator
const loc: IBrowserLocation = (typeof win.location === 'undefined') ? { 'href': 'http://localhost/' } : win.location

// 定数を初期化
sys.__setSysVar('AJAX:ONERROR', (err: any) => { console.log(err) })
sys.__setSysVar('AJAX:ONERROR', (err: unknown) => { console.log(err) })
// オブジェクトを初期化
sys.__setSysVar('DOCUMENT', doc)
sys.__setSysVar('WINDOW', win)
sys.__setSysVar('NAVIGATOR', nav)
sys.__setSysVar('DOM親要素', doc.body)
sys.__setSysVar('DOCUMENT', doc as unknown as NakoValue)
sys.__setSysVar('WINDOW', win as unknown as NakoValue)
sys.__setSysVar('NAVIGATOR', nav as unknown as NakoValue)
sys.__setSysVar('DOM親要素', doc.body as NakoValue)
sys.__setSysVar('ブラウザURL', loc.href)

// 便利なメソッドを定義
Expand All @@ -87,69 +91,86 @@ const PluginBrowser = {
// 「!クリア」でDOMイベントを削除するため
sys.__dom_events = [] // [{}, {}, {} ...]
// DOM追加イベント
sys.__addEvent = (dom: any, event: any, func: any, setHandler: any) => {
// dom
sys.__addEvent = (dom: HTMLElement|string, event: string, func: NakoCallback, setHandler: NakoCallbackEvent) => {
// dom element
let domElement: HTMLElement|null = null
if (typeof (dom) === 'string') {
dom = doc.querySelector(dom)
if (!dom) { throw new Error('DOMイベントが追加できません。要素が見当たりません。') }
domElement = doc.querySelector(dom)
if (!domElement) { throw new Error('DOMイベントが追加できません。要素が見当たりません。') }
} else {
domElement = dom
}
// func
if (typeof (func) === 'string') {
func = sys.__findVar(func, null)
func = sys.__findVar(func, null) as NakoCallback
if (!func) { throw new Error('DOMイベントが追加できません。関数が見当たりません。') }
}
// make wrapper func
const wrapperFunc = (e: any) => {
const wrapperFunc = (e: Event) => {
sys.__setSysVar('対象', e.target)
sys.__setSysVar('対象イベント', e)
// 追加データが得られる場合
if (setHandler) { setHandler(e, sys) }
if (sys.__genMode === '非同期モード') { sys.newenv = true }
return func(e, sys)
if (typeof func == 'function') {
return func(e, sys)
}
return false
}
// add
sys.__dom_events.push({ dom, event, func: wrapperFunc, rawFunc: func })
dom.addEventListener(event, wrapperFunc)
sys.__dom_events.push({ dom: domElement, event, func: wrapperFunc, rawFunc: func })
const domWithEventListenr = dom as { addEventListener: (event: string, func: (e: Event) => void) => void }
if (typeof domWithEventListenr.addEventListener === 'function') {
domWithEventListenr.addEventListener(event, wrapperFunc)
}
}
// キーイベントハンドラ
sys.__keyHandler = (e: any, sys: any) => {
sys.__keyHandler = (e: KeyboardEvent, sys: NakoBrowsesrSystem) => {
sys.__setSysVar('押キー', e.key)
}
// マウスイベントハンドラ
sys.__mouseHandler = (e, sys) => {
const box = e.target.getBoundingClientRect()
sys.__setSysVar('マウスX', e.clientX - box.left)
sys.__setSysVar('マウスY', e.clientY - box.top)
if (e.button !== undefined) {
const buttonLabels = ['左', '中央', '右']
sys.__setSysVar('押ボタン', buttonLabels[e.button])
sys.__mouseHandler = (e: MouseEvent, sys: NakoBrowsesrSystem) => {
const target = e.target as HTMLElement;
if (target && target instanceof HTMLElement) {
const box = target.getBoundingClientRect()
sys.__setSysVar('マウスX', e.clientX - box.left)
sys.__setSysVar('マウスY', e.clientY - box.top)
if (e.button !== undefined) {
const buttonLabels = ['左', '中央', '右']
sys.__setSysVar('押ボタン', buttonLabels[e.button])
}
}
}
// タッチイベントハンドラ
sys.__touchHandler = (e, sys) => {
const box = e.target.getBoundingClientRect()
const touches = e.changedTouches
if (touches.length <= 0) { return }
const ts = []
for (let i = 0; i < touches.length; i++) {
const t = touches[i]
const tx = t.clientX - box.left
const ty = t.clientY - box.top
if (i === 0) {
sys.__setSysVar('タッチX', tx)
sys.__setSysVar('タッチY', ty)
sys.__touchHandler = (e: TouchEvent, sys: NakoBrowsesrSystem) => {
const target = e.target as HTMLElement;
if (target && target instanceof HTMLElement) {
const box = target.getBoundingClientRect()
const touches = e.changedTouches
if (touches.length <= 0) { return }
const ts = []
for (let i = 0; i < touches.length; i++) {
const t = touches[i]
const tx = t.clientX - box.left
const ty = t.clientY - box.top
if (i === 0) {
sys.__setSysVar('タッチX', tx)
sys.__setSysVar('タッチY', ty)
}
ts.push([tx, ty])
}
ts.push([tx, ty])
sys.__setSysVar('タッチ配列', ts)
return ts
}
sys.__setSysVar('タッチ配列', ts)
return ts
}
// DOMイベント削除 (探して削除)
sys.__removeEvent = (dom, event, func) => {
// dom
let domElement: HTMLElement|null = null
if (typeof (dom) === 'string') {
dom = doc.querySelector(dom)
if (!dom) { throw new Error('DOMイベントが削除できません。要素が見当たりません。') }
domElement = doc.querySelector(dom)
if (!domElement) { throw new Error('DOMイベントが削除できません。要素が見当たりません。') }
} else {
domElement = dom
}
// func
if (typeof (func) === 'string') {
Expand All @@ -169,19 +190,19 @@ const PluginBrowser = {
// requestAnimationFrame のためのid
sys.__requestAnimationFrameLastId = 0
// DOMイベント全クリア
sys.__removeAllDomEvent = () => {
sys.__removeAllDomEvents = () => {
sys.__dom_events.forEach(e => {
e.dom.removeEventListener(e.event, e.func)
})
sys.__dom_events = []
// requestAnimationFrame
if (sys.__requestAnimationFrameLastId > 0) {
win.cancelAnimationFrame(sys.__requestAnimationFrameLastId)
(win as Window).cancelAnimationFrame(sys.__requestAnimationFrameLastId)
sys.__requestAnimationFrameLastId = 0
}
}
// DOM取得のために使う
sys.__query = (dom, commandName, isGetFunc) => {
sys.__query = (dom: object|string, commandName: string, isGetFunc: boolean) => {
const elm = (typeof dom === 'string') ? document.querySelector(dom) : dom
if (!elm) {
if (isGetFunc) {
Expand All @@ -201,7 +222,7 @@ const PluginBrowser = {
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = url
script.onload = resolve
script.onload = () => { resolve() }
script.onerror = () => {
reject(new Error(`Failed to load script at url: ${url}`))
}
Expand All @@ -214,13 +235,16 @@ const PluginBrowser = {
type: 'func',
josi: [],
pure: true,
fn: function (sys) {
fn: function (sys: NakoBrowsesrSystem) {
// chart.jsを破棄
if (sys.__chartjs) {
sys.__chartjs.destroy()
const chartjs = sys.__chartjs as { destroy: () => void }
if (typeof chartjs.destroy === 'function') {
chartjs.destroy()
}
}
// 全DOMイベントをクリア
sys.__removeAllDomEvent()
sys.__removeAllDomEvents()
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions src/plugin_browser_api.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { NakoSystem, NakoCallback, NakoCallbackEvent } from '../core/src/plugin_api.mjs'

export interface IKeyEvent extends Event {
key: string
code: string
shiftKey: boolean
ctrlKey: boolean
altKey: boolean
metaKey: boolean
}
export interface ITouchEvent extends Event {
touches: object
}
export interface IBrowserLocation { // 暫定型 (window.location)
href: string
}
export interface IBrowserWindow { // 暫定型 - 本来は Window (ブラウザ以外の環境でもなんとなく動かすために定義)
location: IBrowserLocation
}
export interface IBrowserDocument { // 暫定型 - 本来は Document
body: object
querySelector: (selector: string) => HTMLElement|null
}
export interface NakoDomEvent {
dom: HTMLElement
event: string
func: (e: Event) => void
rawFunc: NakoCallback
}
export type NakoDom = HTMLElement|string

export interface NakoBrowsesrSystem extends NakoSystem {
__query(dom: NakoDom, commandName: string, isGetFunc: boolean): object|null
__addEvent(dom: NakoDom, event: string, func: NakoCallback, setHandler: NakoCallbackEvent|null): void
__keyHandler(e: KeyboardEvent, sys: NakoBrowsesrSystem): void
__mouseHandler(e: MouseEvent, sys: NakoBrowsesrSystem): void
__touchHandler(e: TouchEvent, sys: NakoBrowsesrSystem): void
__removeEvent(dom: NakoDom, event: string, funcStr: NakoCallback): void
__removeAllDomEvents(): void
__tohtml(text: string): string
__tohtmlQ(text: string): string
__dom_events: NakoDomEvent[]
__requestAnimationFrameLastId: number
__chartjs: object
}

Loading

0 comments on commit 33af9cb

Please sign in to comment.