世界地図のSVGをHTMLReader.frameworkでparseして、目的のノードに塗り色の指定を行い、WkWebView上で表示するAppleScriptです。
–> Download selectCountry2(Code-signed AppleScript executable applet)
昨日のものがあくまでSVGのParseと表示が目的の試作品であったのに対し、本Scriptは連続してポップアップメニューから対象を選んで表示するというものです。
同様にmacOS 10.15.1上で作成しましたが、このバージョンのOS環境ではAppleScriptアプレットにFrameworkを入れてAppleScript内から呼び出すことが標準のランタイム(Script Editorから書き出した場合)では行えないようになっており、Script Debuggerから「Application(Enhanced)」で書き出さないと呼び出せないようです(これはちょっとひどいかも、、、、)。
世界地図はWikipediaから拾ってきたもので、ISO国コードではなく名称でIDが振ってあり、日本もJapanではなくHokkaido、Honshu、Shikoku、Kyushuuに分けて登録されています。
▲Script Editor上でサードパーティFramework呼び出しの動作ができているのは、この実行環境でSIPを解除してあるからです
AppleScript名:アラートダイアログ上のWebViewに世界地図を表示 v2b.scptd |
— – Created by: Takaaki Naganoya – Created on: 2019/11/18 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "AppKit" use framework "HTMLReader" –https://github.com/nolanw/HTMLReader 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 NSColor : a reference to current application’s NSColor property NSString : a reference to current application’s NSString property NSImage : a reference to current application’s NSImage property NSScreen : a reference to current application’s NSScreen 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 HTMLDocument : a reference to current application’s HTMLDocument 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 theResult : 0 property returnCode : 0 property aWebView : missing value property aLog : missing value property tmpURL : "" tell current application set mePath to ((path to me) as string) & "Contents:Resources:World_map_-_low_resolution.svg" set svgCon to read (mePath as alias) set aWidth to 950 set aHeight to 650 set paramObj to {myMessage:"Browse World map", mySubMessage:"This is a sample SVG World map", targContents:svgCon, myWidth:(aWidth), myHeight:(aHeight)} –my browseLocalWebContents:paramObj my performSelectorOnMainThread:"browseLocalWebContents:" withObject:(paramObj) waitUntilDone:true return aLog end tell on browseLocalWebContents:paramObj set aMainMes to (myMessage of paramObj) as string set aSubMes to (mySubMessage of paramObj) as string set tmpURL to (targContents of paramObj) as string –local contents set aWidth to (myWidth of paramObj) as integer set aHeight to (myHeight of paramObj) as integer set aView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) –Ppopup Buttonをつくる set a1Button to current application’s NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aHeight – 26, 200, 24)) pullsDown:(false) a1Button’s removeAllItems() –Menuの中身を作る set aHTML to current application’s HTMLDocument’s documentWithString:(tmpURL) set fList to (aHTML’s nodesMatchingSelector:"path")’s valueForKeyPath:"attributes.id" set fList to fList’s sortedArrayUsingSelector:"compare:" a1Button’s addItemWithTitle:"▼Select" repeat with i in fList (a1Button’s addItemWithTitle:(i as string)) end repeat a1Button’s setTarget:(me) a1Button’s setAction:("mySelector:") a1Button’s setEnabled:(true) set aWebView to makeWebViewAndLoadContents(tmpURL, aWidth, aHeight – 40) of me aView’s addSubview:a1Button aView’s addSubview:aWebView — 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:aView 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 browseLocalWebContents: on doModal:aParam set (my returnCode) to (aParam’s runModal()) as number end doModal: on viewDidLoad:aNotification return true end viewDidLoad: –Popup Action Handler on actionHandler:sender set aTitle to title of sender as string end actionHandler: 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 mySelector:aSender set targetCountry to (aSender’s title()) as string set aHTML to current application’s HTMLDocument’s documentWithString:(tmpURL as string) set eList to (aHTML’s nodesMatchingSelector:"path") as list set fList to (aHTML’s nodesMatchingSelector:"path")’s valueForKeyPath:"attributes.id" –Search Target Country set aRes to (fList)’s indexOfObject:(targetCountry) if (aRes = current application’s NSNotFound) or (aRes > 9.99999999E+8) then error "Target country not found" end if set aRes to aRes + 1 –Rewrite target country’s fill color on SVG set tmpNode to contents of item aRes of (eList) (tmpNode’s setObject:"Red" forKeyedSubscript:"fill") –Change Target Country’s fill color set svgCon to (tmpNode’s |document|()’s serializedFragment()) as string –HTMLReaderはこういう処理ができるところが好き aWebView’s loadHTMLString:svgCon baseURL:(missing value) end mySelector: on makeWebViewAndLoadContents(aContents as string, aWidth as integer, aHeight as integer) set aConf to WKWebViewConfiguration’s alloc()’s init() –指定URLのJavaScriptをFetch set jsSource to my fetchJSSourceString(aContents) 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 aWebView’s setOpaque:false aWebView’s setBackgroundColor:(NSColor’s clearColor()) –aWebView’s scrollView()’s setBackgroundColor:(NSColor’s clearColor()) aWebView’s loadHTMLString:aContents baseURL:(missing value) return aWebView end makeWebViewAndLoadContents |