アラートダイアログ上にWkWebViewを作成して、さまざまなグラフや3Dアニメーションを表示してきた「箱庭ダイアログ」の1つの到達点、「periodictable」(元素周期表)選択UIの表示デモAppleScriptです。
実行は掲載リストではなく上記のリンクからダウンロードしたAppleScriptバンドルを、かならずスクリプトエディタでオープンして(Script Debugger不可)、Controlキーを押しながらスクリプトエディタの「スクリプト」メニューから「フォアグラウンドで実行」コマンドで実行してください。
「フォアグラウンド」はApple(の外注のローカライズ業者による)ローカライズ内容が間違っていて、実際には「メインスレッドで実行」が正しいのですが、まあいいです。
以前に掲載したバージョン(v3)は、掲載後しばらくはそのまま動いていることが確認されたのですが、その後のCDN上のJavaScriptライブラリのアップデートにともない、動作しなくなっていました。本v4はその点を解決したもので、技術的により進化したというよりも、「勝手に動かなくなる点に対処した」程度のものとお考えください。
periodictableのUser Interface自体、目を惹くものであり、とても楽しいものです。ただ、真剣にその内容を解析し、汎用的に利用できるかどうかを検討してみると、おおよそ120個程度の要素に対して、重みづけを与えずに自由選択するような用途でないと実用性が得られないことがわかりました。たいてい、情報には重要度などの重みがありますが、本User Interfaceはそれがあると邪魔な感じです。
また、少ないデータ……2個や3個の要素から選択するのでは、用をなしません。用途が限定されすぎているというべきなのか、この用途にしか合わないというべきなのか。
JavaScriptとAppleScriptの間での選択項目のやり取りを行う手段についても、edama2氏が実際に稼働するデモを作ったのを見せてもらい、たしかにそうした処理ができることを確認しています。
それでも、いまひとつ実用性がないので、あくまで本プログラムは「デモ用」と割り切っています。
「CDN上のJavaScriptライブラリがアップデートして動かなくなる問題」についても、1つの解決策が見えてきました。ローカルにJavaScriptライブラリを配置して読み込んで使えばいいというものです。実際に、本ScriptバンドルのResourceフォルダ内にそれらのファイルが入っています。
これで勝手にアップデートされないため、放っておくと動かなくなるといった問題への解決策となっています。ただ、その一方でメイン処理を呼び出すさいに強制的なメインスレッド実行を行わせても、実行できないという謎の現象が発生。これについては、問題解決の手段自体はあるはずです(たぶん)。
AppleScript名:アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v4.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/06/13 – Modified on: 2023/03/07 — – Copyright © 2020-2023 Piyomaru Software, All Rights Reserved — use AppleScript version "2.7" use framework "Foundation" use framework "AppKit" use framework "WebKit" use scripting additions property |NSURL| : a reference to current application’s |NSURL| property NSAlert : a reference to current application’s NSAlert property NSString : a reference to current application’s NSString property NSButton : a reference to current application’s NSButton property WKWebView : a reference to current application’s WKWebView property WKUserScript : a reference to current application’s WKUserScript property NSURLRequest : a reference to current application’s NSURLRequest property NSRunningApplication : a reference to current application’s NSRunningApplication property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property WKUserContentController : a reference to current application’s WKUserContentController property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd property returnCode : 0 on run –https://www.cresco.co.jp/blog/entry/7427/ — By sgi-chang @ UX Design Center set myStr to (POSIX path of (path to me)) & "/Contents/Resources/index.html" set paramObj to {myMessage:"WebGL & three.js Test", mySubMessage:"This is a WebGL UI using three.js", htmlPath:myStr} my browseFileWebContents:paramObj –for debug –my performSelectorOnMainThread:"browseFileWebContents:" withObject:(paramObj) waitUntilDone:true end run on browseFileWebContents:paramObj set aMainMes to myMessage of paramObj set aSubMes to mySubMessage of paramObj set htmlPathStr to (htmlPath of paramObj) set aWidth to 1600 set aHeight to 900 –WebViewをつくる set aConf to WKWebViewConfiguration’s alloc()’s init() –指定HTML内のJavaScriptをFetch tell current application set htmlString to read ((POSIX file htmlPathStr) as alias) as «class utf8» end tell set jsSource to pickUpFromToStr(htmlString, "<script src", "</script>") of me set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true set userContentController to WKUserContentController’s alloc()’s init() userContentController’s addUserScript:(userScript) aConf’s setUserContentController:userContentController set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf aWebView’s setNavigationDelegate:me aWebView’s setUIDelegate:me aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true using terms from scripting additions set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me)) end using terms from set htmlURL to current application’s |NSURL|’s fileURLWithPath:htmlPathStr aWebView’s loadFileURL:(htmlURL) allowingReadAccessToURL:(bURL) — set up alert set theAlert to NSAlert’s alloc()’s init() tell theAlert its setMessageText:aMainMes its setInformativeText:aSubMes its addButtonWithTitle:"OK" –its addButtonWithTitle:"Cancel" its setAccessoryView:aWebView set myWindow to its |window| end tell — show alert in modal loop NSRunningApplication’s currentApplication()’s activateWithOptions:0 my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true –Stop Web View Action set bURL to |NSURL|’s URLWithString:"about:blank" set bReq to NSURLRequest’s requestWithURL:bURL aWebView’s loadRequest:bReq if (my returnCode as number) = 1001 then error number -128 end browseFileWebContents: on doModal:aParam set (my returnCode) to (aParam’s runModal()) as number end doModal: on viewDidLoad:aNotification return true end viewDidLoad: on fetchJSSourceString(aURL) set jsURL to |NSURL|’s URLWithString:aURL set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value) return jsSourceString end fetchJSSourceString on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string) set a1Offset to offset of s1Str in aStr if a1Offset = 0 then return false set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr set a2Offset to offset of s2Str in bStr if a2Offset = 0 then return false set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr return cStr as string end pickUpFromToStr –リストを任意のデリミタ付きでテキストに on retArrowText(aList, aDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retArrowText on array2DToJSONArray(aList) set anArray to current application’s NSMutableArray’s arrayWithArray:aList set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding) return resString end array2DToJSONArray on parseByDelim(aData, aDelim) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set dList to text items of aData set AppleScript’s text item delimiters to curDelim return dList end parseByDelim |