接上篇, 接着學習 kityminder. css
== core/keyreceiver.js == node
extend class Minder {
init-hook(): 構造時設置選項, 偵聽 'paperrender' 事件, 以調用 _initKeyReceiver()
_initKeyReceiver(): 建立 DOM 元素 <input class='km-receiver'>, 添加到容器 <div> 中.
在此 <input> 上偵聽 keydown, keyup, keypress 等多個事件, 而後轉給 minder 對象處理.
看起來彷佛是用於專門接收 key 事件的, 也許容器不方便接收 key 事件?
事件 on_focus(): 設置上面的 <input> 爲 focus.
彷佛是將 <div> 的 focus,blur 同步給 <input>.
} 算法
== core/module.js == 數組
閉包變量: _modules = {}, 註釋爲已註冊的模塊. promise
對外提供函數 Module.register(name, module): 註冊一個模塊.
如今對什麼是模塊的概念不太清晰, 另 seajs 也是加載模塊, 那麼有區別? 閉包
extend class Minder { // 註釋: 模塊聲明週期維護.
init-hook(): 調用 _initModules()
_initModules(): 某種(預先?)模塊加載機制, 可能先要註冊模塊, 而後這裏在 minder 構造時完成一些加載工做.
還涉及 command, event, renderer, shortcut 等等, 稍後細研究吧.
_garbage(): 刪掉全部子節點, 等於清空文檔?
destroy(): 清空文檔, for-each(modules).destroy(this)
reset(): 清空, for-each(modules).reset(this); 至關於每模塊提供 destroy, reset 方法可被調用.
} app
實際查看了一下, 在 minder 對象中有一個 _modules{}, 裏面有 Arrange, Clipboard, Connect, ...
大約 30 個模塊? ._query 爲 null, ._rendererClasses 有 left,right,top 等幾個. ._commands 前面
遇到過. ide
模塊看起來是一種擴展功能的機制, 稍後須要更深刻看看. 函數
== core/readonly.js : 只讀模式支持 == 工具
extend class Minder {
init-hook(): 若是選項有 readonly, 則設置爲 disabled.
disable(): 禁用命令. 對命令對象的 query 方法包裝(修飾)一下, 在 readonly 狀態下返回 null/0.
產生 'readonly' 事件. 設置狀態 _status='readonly'
enable(): 恢復命令. 去掉 query command 的包裝. 設置狀態爲 'normal'.
}
由此知道 minder._status 表示的文檔狀態是 normal, readonly 等幾種.
== core/render.js ==
class Renderer {
ctor(node): this.node = node; 問題: 一個實例對應一個 node? 這裏 node 是什麼?
create(node): throw ('not impl') 也許設計由派生的子類來實現.
update(): draw(), place()
draw(): throw 'not impl'; 也許子類實現.
place(): throw 'not impl'; 也許子類實現.
還有一些方法略, 大體可認爲是一個接口聲明, 幾個主要?功能可能須要子類實現, 因此應該有(數個?)實現子類?
}
extend class Minder {
renderNodeBatch(nodes): 與 node render 機制有關, 如今理解不了, 須要稍後.
renderNode(node): render 單個節點. 彷佛有或建立 node renderers[],
而後 for-each(renderer).do_sth()
在 render 以前產生 'beforerender' 事件, 以後產生 'noderender' 事件.
}
實際查看了一下例子, root._renderers[] 含11項, 分別是 TextRenderer, PriorityRenderer 等等.
root 的幾個子節點每一個也都有 _renderers[], 也都是 11 項... 每一個節點都要建立這麼多嗎?
在 minder._rendererClasses{} 彷佛保存有 name=>renderers[] 的映射.
extend class MinderNode {
render(): 即 minder.renderNode(此節點)
renderTree(): 即 minder.renderNodeBatch(全部子孫節點)
getRenderer(type): 獲得該 type 的 renderer. 這裏 type 有哪些須要後續瞭解.
getContentBox(): 可能每一個 node 對應有一個 content-box, 對應類爲 kity.Box()
getRenderBox(): 相關概念有 renderer, content-box, transform-matrix 等. 暫不清楚.
}
另外一個小問題, 在建立 node._renderers[] 的時候, 是用 new Renderer(node), 但查看時倒是不一樣的
Renderer 子類(如 TextRenderer, ImageRenderer等), 那麼 new 發生了什麼?
Renderer 是一個重要的概念, 咱們須要更多學習...
== core/connect.js ==
閉包變量 _connectProviders{} 註釋爲: 連線提供方.
這裏註冊一個 'default' 的 connect-provider. 細節稍後.
extend class MinderNode {
getConnect(): 註釋爲獲取當前節點的連線類型. 缺省返回 'default', 可能名字對應 connect-provider
getConnectProider(): 根據名字找該名字的 connect-provider.
getConnection(): 獲得當前節點的連線對象. 實際查看這個對象是一個 Path 類的實例.
}
extend class Minder {
getConnectContainer(): 獲得對應成員變量.
createConnect(node): 建立 node._connection = kity.Path 對象, 更新 connect.
removeConnect(node): 遍歷?刪除全部子孫節點的 ?
updateConnect(node): 獲得相關對象: parent(node), connection(kity.Path), connect-provider,
調用 provider() 方法對 node<--connect-->parent 創建連線吧. 猜想 default connect-provider
就用簡單曲線連起來. 這樣連線應對應一個 path 對象, 具體怎麼曲線由 provider 計算...
}
register module Connect {
init(): 彷佛是建立一個 <g> 元素, 用於容納全部連線的 <path>.
events: { // 回顧 module.js , 這裏至關於偵聽以下事件.
on 'nodeattach': 建立 connect.
on 'nodedetach': 刪除 connect.
on 'layoutapply layoutfinish noderender': 更新 connect.
}
}
這裏正好能夠回顧一下 module, 瞭解註冊模塊要作什麼, 如今已知模塊可偵聽一些事件.
查看 km._eventCallbacks{}, 裏面有多種事件對應的 callback[].
== core/layout.js ==
閉包變量 _layouts{}, 用於註冊 name->layout 的映射.
經過查看, 裏面有 bottom, filetree-xxx, fish-bone-xxx, mind 等多種佈局實現(子類).
缺省 layout 爲 'mind'.
// 此類不少註釋摘抄過來: 佈局基類, 具體佈局(子類)須要從該類派生.
class Layout {
doLayout(): 子類須要實現的佈局算法. 該算法輸入一個節點, 排布該節點的子節點(相對父節點的變換)
註釋給出的例子中最後是 child.setLayoutTransform(transform-matrix), 即要給出最終變換矩陣.
align(): 對齊指定的節點. 根據對齊到哪個邊, 產生新的變換 matrix (疊加一個平移變換).
stack(): ?多是將一組節點沿某個 axis(軸) 疊成一排(列)?
move(): 平移一組節點.
getBranchBox(): 獲取給定的節點[]所佔的佈局區域 (box?), 是單個node box 的總的 merge. (UnionRect)
getTreeBox(): 工具方法:計算給定的節點的子樹所佔的佈局區域. 彷佛意思是包含全部子節點的 box.
getOrderHint(): 可能由子類實現. 這裏返回一個空數組.
}
// 註釋: 佈局支持池子管理 (什麼是池子...?)
extend class Minder {
init-hook(): 調用刷新 refresh()?
getLayoutList(): ?
getLayoutInstance(name): 建立指定名字的 layout 實現(子)類.
}
// 註釋: MinderNode 上的佈局支持.
extend class MinderNode {
get/setLayout(): 得到當前節點的佈局名稱. 若是未給出就使用父節點的 layout, 直到缺省爲 'mind'.
layout(name): 設置指定 name 的佈局, 並調用 minder.layout()
get/setLayoutTransform(): 獲取當前節點相對於父節點的佈局變換. (返回是一個 matrix)
getGlobalLayoutTransformPreview(): 第一輪佈局計算後, 得到的全局佈局位置. (返回合併後的 matrix?)
getLayoutPointPreview(): ?
get/setGlobalLayoutTransform(): 得到節點相對於全局的佈局變換. (?)
set(): 相對於全局的變換(冗餘優化), 暫不明白.
get/setVertexIn(p): 多是設置連線的進入點?
get/setVertexOut(p): 多是設置連線的出點?
getLayoutVertexIn(): 對 in 點用 global-layout-transform 進行變換?
getLayoutVertextOut(): 對 out 點 xxx 變換.
get/setLayoutVectorIn(): 獲取/設置某種向量 (kity.Vector?)
get/setLayoutVectorOut(): 也許是入點/出點方向向量?
getLayoutBox(): 對 content-box 進行 glt 變換.
getLayoutPoint(): 獲得佈局原點?
get/set/has/resetLayoutOffset(): 獲取/設置佈局相關的一個點 (kity.Point).
get/isLayoutRoot():
}
extend class Minder {
layout(): 清空前次layout; 第一輪佈局, 第二佈局; 應用佈局結果; 發佈 layout 事件.
會遞歸調用子節點的 layout(). 彷佛實際用 layout-instance.doLayout() 實質佈局.
refresh(): 多是徹底重繪/重佈局. 發佈事件, 以及 interact-change().
applyLayoutResult(): 彷佛應用動畫給更新, 若是過複雜則不動畫.
}
佈局是重點功能, 稍後回來再回顧.
== core/theme.js ==
閉包變量 _themes{}, 估計存放支持的全部 theme. 查看了一下大約有20種, 大約是顏色+樣式組合.
數據形式像 css. 在 src/theme/ 下面有 6 個 js, 用於註冊多種 theme.
extend class Minder {
static getThemeList(): 即獲取 _themes{}.
init-hook: 設置(缺省) theme.
useTheme(): 切換腦圖實例上的主題.
實驗: 在控制檯上執行 km.useTheme('fresh-green') 果真變爲綠色主題~
get/setTheme(): 獲取/設置主題, 發佈事件.
getStyle(): 得到腦圖實例上的樣式. 可能像 css 方式訪問.
getNodeStyle(): 獲取指定節點的樣式.
}
extend class MinderNode {
getStyle(): 等價於 minder.getNodeStyle(this)
}
register module Theme {
選項略;
commands: { 爲 minder 添加命令 ThemeCommand }
}
如今仍是未徹底理解 register module, 是否這些註冊等也均可以用 init-hook 等方式完成?
== core/template.js 顯示模板(形式) ==
閉包變量 _templates{}. 查看一下大體有 6 種: default,filetree, fish-bone, ...
這裏 template 應是指圖的形式, 如缺省,魚骨圖,文件樹等.
extend class Minder {
static getTemplateList(): 即獲取 _templates{}
use/get/setTemplate(): 切換到該形式.
getTheme(): 被這裏修改了.
}
extend class MinderNode {
getLayout(): 這裏修改/加強了原 getLayout() 方法, 根據 template 是否支持.
getConnect(): 相似的修改.
}
register module TemplateModule {
添加 template 命令, 容許切換顯示形式(模板).
}
== core/promise.js ==
這多是外部某個 js 代碼, 因不瞭解 promise 的意圖, 暫時先跳過.
== core/_boxv.js ==
調試工具, 爲 kity.Box 提供一個可視化的渲染. 當 url 中含特定 boxv 時.
extend class kity.Box {
visualization get: 設置 vrect 大小.
}
extend class Minder {
init-hook: 註冊事件.
on event paperrender: 建立調試用 vrect, 在上面改變大小. 有空作作實驗.
}
== core/patch.js 打補丁 ==
extend class Minder {
applyPatches(): 應用所給補丁[]. 如今不瞭解在補丁什麼...?
}
這裏結束了 core/*.js 小節, 下面是 module/*.js 部分. 那就放下一篇筆記吧.