Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: 10.15savvy

指定のドメインのIPアドレスを指定DNSで引いて返す

Posted on 5月 26, 2020 by Takaaki Naganoya

指定のドメインのIPアドレスを、指定のDNSサーバーで引いて結果を返すAppleScriptです。

DNS系のFramework(Objective-Cで書いてあるもの)はいろいろためしてみたものの、不思議とどれも動作が重くて、このようにshell commandを呼び出したほうが手軽で高速でした。

# うまく動いていなかったために遅かった、というのが正確なところかも。タイムアウトエラーを起こして処理が完了しないものばかりだったので、、、書き換えがうまく行っていなかった可能性が50%以上あります

nslookupの結果を取り出すためにいろいろやっていますが、ありもののルーチンを引っ張り出して加工してしているだけです。

apple.comのように、CDNサービスを利用してアクセス負荷分散を行なっているようなドメインだと、問い合わせごとにIPアドレスが変わるようです。

一方で、piyocast.comのように固定ホスト(バーチャルホストではありますが)で細々とホスティングしているようなドメインでは、IPアドレスが毎回変わるということはありません。

AppleScript名:指定のドメインのIPアドレスを指定DNSで引いて返す v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/25
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property NSScanner : a reference to current application’s NSScanner
property NSMutableArray : a reference to current application’s NSMutableArray

set aDomain to "apple.com"
set aDNS to "8.8.4.4"
set dnRes to getIPAddress(aDomain, aDNS) of me
–> {serverName:"apple.com", serverAddr:{"17.172.224.47", "17.178.96.59", "17.142.160.59"}}–CDNの影響でアドレスが頻繁に変わる?

set dnRes to getIPAddress("piyocast.com", aDNS) of me
–> {serverName:"piyocast.com", serverAddr:{"157.112.183.74"}}

on getIPAddress(aDomain, aDNS)
  set searchStr to "answer:"
  
  
using terms from scripting additions
    set aRes to do shell script ("nslookup " & aDomain & " " & aDNS)
    
set bRes to offset of searchStr in aRes
  end using terms from
  
  
if bRes = 0 then return false
  
  
set cRes to text (bRes + (length of searchStr) + 1) thru -1 of aRes
  
  
set adRes1 to extractStrFromTo(cRes, "Name:", return) of me
  
set adRes2 to extractStrFromTo(cRes, "Address:", return) of me
  
  
set outList to {}
  
set erList to {}
  
repeat with i from 1 to (length of adRes2)
    set j1 to contents of (item i of adRes1)
    
set j2 to contents of (item i of adRes2)
    
if j1 is equal to aDomain then
      set the end of outList to j2
    else
      set the end of erList to {j1, j2}
    end if
  end repeat
  
  
return {serverName:j1, serverAddr:outList}
end getIPAddress

–offset命令の実行を横取りして高速実行(x2.5 faster)
on offset of searchStr in str
  set aRes to getOffset(str, searchStr) of me
  
return aRes
end offset

on getOffset(str, searchStr)
  set d to divideBy(str, searchStr)
  
if (count d) is less than 2 then return 0
  
return (length of item 1 of d) + 1
end getOffset

on divideBy(str, separator)
  set delSave to AppleScript’s text item delimiters
  
set the AppleScript’s text item delimiters to separator
  
set strItems to every text item of str
  
set the AppleScript’s text item delimiters to delSave
  
return strItems
end divideBy

–指定文字と終了文字に囲まれた内容を抽出
on extractStrFromTo(aParamStr, fromStr, toStr)
  set theScanner to NSScanner’s scannerWithString:aParamStr
  
set anArray to NSMutableArray’s array()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    set {theResult, theKey} to theScanner’s scanUpToString:fromStr intoString:(reference)
    
theScanner’s scanString:fromStr intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:toStr intoString:(reference)
    
if theValue is missing value then set theValue to "" –>追加
    
theScanner’s scanString:toStr intoString:(missing value)
    
anArray’s addObject:theValue
  end repeat
  
  
return (anArray as list)
end extractStrFromTo

★Click Here to Open This Script 

Posted in Internet | Tagged 10.13savvy 10.14savvy 10.15savvy NSMutableArray NSScanner | Leave a comment

アラートダイアログ上にWebViewでGoogle Chartsを表示(Geo Chart 1)

Posted on 5月 24, 2020 by Takaaki Naganoya

NSAlertのアラートダイアログ上にGoogleChartsを用いたGeoChartを表示するAppleScriptです。

Geo Chartに表示されている地図の上でマウスカーソルを移動させると、Chartが反応してデータ表示を行います。

本Scriptに掲載しているAPI KeyはGoogleに掲載されているサンプル用のものであり、サンプルデータの表示以外には使用できません。Google開発者アカウントを取得し、API Keyを取得して記入しておく必要があります。

AppleScript名:アラートダイアログ上にWebViewでGoogle Chartを表示(Geo Chart 1).scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/02
—
–  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 "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSButton : a reference to current application’s NSButton
property NSBundle : a reference to current application’s NSBundle
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
property aBrowserAgentRes : ""

set mapsAPIKey to "AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY" –for demonstration only

my performSelectorOnMainThread:"getSafariUserAgentString:" withObject:(missing value) waitUntilDone:true

–Sample Data
set aList to {{"Country", "Popularity"}, ¬
  {"Germany", 200}, ¬
  {
"United States", 300}, ¬
  {
"Brazil", 400}, ¬
  {
"Canada", 500}, ¬
  {
"France", 600}, ¬
  {
"RU", 700}}

set aJsonArrayStr to array2DToJSONArray(aList) of me

–Map Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<head>
<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
google.charts.load(’current’, {’packages’:[’geochart’], ’mapsApiKey’: ’%@’});
google.charts.setOnLoadCallback(drawRegionsMap);

function drawRegionsMap() {
var data = google.visualization.arrayToDataTable(%@);

var options = {};

var chart = new google.visualization.GeoChart(document.getElementById(’regions_div’));
chart.draw(data, options);
};
</script>
</head>
<body>
  <div id=\"regions_div\" style=\"width: 900px; height: 500px;\"></div>
</body>
</html>"

set aString to NSString’s stringWithFormat_(myStr, mapsAPIKey, aJsonArrayStr) as string

set paramObj to {myMessage:"Google GeoChart Test", mySubMessage:"This is a simple GeoChart using google charts", htmlStr:aString}
–my browseStrWebContents:paramObj –for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 920
  
set aHeight to 520
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</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
  
aWebView’s setCustomUserAgent:(my aBrowserAgentRes)
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
aWebView’s loadHTMLString:htmlString baseURL:(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 browseStrWebContents:

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 NSString’s alloc()’s initWithData:jsonData encoding:(NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

–Safariと同じUser Agentの文字列を取得する
on getSafariUserAgentString:anObject
  set aBundle to NSBundle’s bundleWithIdentifier:"com.apple.Safari"
  
set aVer to (aBundle’s infoDictionary()’s objectForKey:"CFBundleShortVersionString") as text
  
–>  "9.0.2"
  
  
set aBuildNo to (aBundle’s infoDictionary()’s objectForKey:"CFBundleVersion") as text
  
–>  "11601.3.6"
  
  
set {v1, v2, v3} to parseVersionNumber(aBuildNo) of me
  
set aV1 to NSString’s stringWithString:v1
  
set bV1 to aV1’s substringFromIndex:2 –3 characters from tail –?????
  
–> "601"
  
  
set bStr to retStrFromArrayWithDelimiter({bV1, v2, v3}, ".") of me
  
  
set aWebView to WebView’s alloc()’s init()
  
set aRes to (aWebView’s stringByEvaluatingJavaScriptFromString:"navigator.userAgent") as text
  
–>  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.6 (KHTML, like Gecko)"
  
  
set aBrowserAgentRes to (aRes & " Version/" & aVer & " Safari/" & bStr)
end getSafariUserAgentString:

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on parseVersionNumber(a)
  set aStr to current application’s NSString’s stringWithString:a
  
set aRes to (aStr’s componentsSeparatedByString:".")
  
set bRes to aRes’s allObjects()
  
return bRes as list
end parseVersionNumber

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSArray NSBundle NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

アラートダイアログのウィンドウタイトル部分にアイコン指定

Posted on 5月 23, 2020 by Takaaki Naganoya

アラートダイアログのウィンドウタイトル部分に任意の画像をアイコンとして表示するAppleScriptです。

本来、NSWindowのタイトル部分にアイコン表示を行うワザのようです。なにか、Cocoaのバグのような仕様を使っているようです。本来、タイトル部分に直接アイコンを表示させることはできないのですが、ドキュメントのURLを指定すると、該当するパス(URL)の書類アイコンを指定する機能はあります。


▲Mac App Store上で販売中のAppleScriptで開発したアプリケーション「Kamenoko」でも、ウィンドウにアイコン表示するコードが使われています。本Scriptではなく、もっとまっとうな方法で

そこに、存在しないURLを指定すると、直後にアイコン指定できるという、、、どこで役立つのかわかりませんが、そういう方法もあるということで。

AppleScript名:アラートダイアログでウィンドウタイトル部分にアイコン指定
— Created 2020-05-08 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property |NSURL| : a reference to current application’s |NSURL|
property NSImage : a reference to current application’s NSImage
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSImageNameComputer : a reference to current application’s NSImageNameComputer
property NSWindowDocumentIconButton : a reference to current application’s NSWindowDocumentIconButton

property returnCode : 0

–Get Computer Icon
set anImage to getComputerIcon() of me
set aMainMes to "TEST"
set aSubMes to "Window title icon TEST"
set wTitle to "Window Title"

set paramObj to {myMessage:aMainMes, mySubMessage:aSubMes, myWinTitle:wTitle, myImage:anImage}
–my displayAlertDialog:paramObj

my performSelectorOnMainThread:"displayAlertDialog:" withObject:(paramObj) waitUntilDone:true

on displayAlertDialog:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set anImage to myImage of paramObj
  
set aWinTitle to myWinTitle of paramObj
  
  
— 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 setIcon:anImage
    
set aWin to its |window|()
  end tell
  
  
aWin’s setTitle:aWinTitle
  
  
aWin’s setRepresentedURL:(|NSURL|’s URLWithString:"WindowTitle") –Dummy URL
  (
aWin’s standardWindowButton:(current application’s NSWindowDocumentIconButton))’s setImage:(anImage)
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
end displayAlertDialog:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on getComputerIcon()
  return NSImage’s imageNamed:(NSImageNameComputer)
end getComputerIcon

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSImage NSImageNameComputer NSRunningApplication NSURL NSWindowDocumentIconButton | Leave a comment

自分のウィンドウのフルスクリーン化 v3

Posted on 5月 22, 2020 by Takaaki Naganoya

Xcode上で作成したAppleScriptアプリケーションのウィンドウをフルスクリーン化するAppleScriptです。

–> download fullScreenTestv3 (Xcode project archive)

前バージョンを実際にアプリケーションに組み込んで実行してみたところ、メニューバーを表示しないうえにツールバー(NSToolbar)も非表示状態でフルスクリーン化したうえに、通常表示状態に戻ってこれませんでした。戻ってくるにはアプリケーションを終了(Command-Q)するしかありませんでした。

ゲームならこれでいいと思うのですが、通常のアプリケーションでフルスクリーンモードから戻ってこられないのは困りますし、メニューやツールバーが使えないのは困ります。

そこで、複数あるうちの別のやりかたを試してみました。本テストアプリケーションのツールバー上の左側のボタンが前バージョンと同じ働きをするもの、右側が新規に試したものです。

ツールバーの右側のボタンをクリックすると、ウィンドウの緑色のボタンをクリックして全画面表示させたのと同じ動きを行います。


▲ビルドして起動したところ


▲ツールバー左側のボタンをクリックして全画面表示させたところ。全画面表示されるが、ツールバーもメニューも表示されない。Command-Qで終了しないと解除されない


▲ツールバー右側のボタンをクリックして全画面表示させたところ。もう一度クリックすると通常表示モードに戻る


▲自分のアプリケーション(Kamenoko)のツールバーに組み込んで実験したところ(制作中のv1.1)

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— fullScreenTest
—
— Created by Takaaki Naganoya on 2020/05/21.
— Copyright © 2020 Takaaki Naganoya. All rights reserved.
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property theWindowView : missing value
  
  
on applicationWillFinishLaunching:aNotification
  
end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
on clicked:aSender
    set aTag to (tag of aSender) as integer
    
    
if aTag = 10 then
      set curScreen to theWindow’s screen()
      
set fMode to (theWindowView’s inFullScreenMode) as boolean
      
      
if fMode = true then
        –Can not return from Full Screen Mode. Quit this test app to return from full screen mode
        
theWindowView’s exitFullScreenModeWithOptions:(missing value)
      else
        –Enter Full Screen Mode
        
theWindowView’s enterFullScreenMode:(curScreen) withOptions:(missing value)
      end if
      
    else if aTag = 20 then
      set fMode to (theWindowView’s inFullScreenMode) as boolean
      
      
if fMode = true then
        –Exit Full Screen Mode
        
theWindow’s toggleFullScreen:(missing value)
      else
        –Enter Full Screen Mode with Toolbar
        
theWindow’s toggleFullScreen:theWindow
      end if
    end if
    
  end clicked:
end script

★Click Here to Open This Script 

Posted in AppleScript Application on Xcode | Tagged 10.13savvy 10.14savvy 10.15savvy NSView NSWindow | Leave a comment

ダブルクリックとコンテクストメニュー表示をサポートするボタン

Posted on 5月 22, 2020 by Takaaki Naganoya

Xcode上で作成するAppleScriptアプリケーションで、ダブルクリックとコンテクストメニュー表示を受け入れるボタンのプロジェクトの試作品です。

–> Download Xcode Projext (doubleClick v2)

ボタンでシングルクリックを受け付けるのは簡単ですが、ダブルクリックを受信するためには、少し手間がかかります。まして、コンテクストメニュー表示は、、、、、

この試作品では、クリックされたボタンを識別できていません。ダブルクリックされたボタンのTagとか、コンテクストメニュー表示させたボタンのTagを取得できるように改変したいところです。

こうした(↑)テーマセレクタで、ダブルクリックでそのままテーマ選択を行えるように対処したいところです。テーマセレクタとか環境設定なんて、アプリケーション開発の最後のほうでやっつけ的に行うので、それほど気合いを入れて作っているものではありません(個人の見解です)。

当初はもっと仕様的に「盛った」ものを作ろうとデザインしたのですが、いざ作ってみたら技術的に難しすぎたので、技術的な難易度を大幅に下げて実装してみました(ここで妥協ができないとモノが仕上がりません)。

自分はRadio Buttonに画像を載せて「選択状態だけとれればいい」と割り切って実装しましたが、たしかにダブルクリックぐらいは受け付けたほうがよいでしょう。Keynoteのテーマセレクタのように。

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— doubleClick
—
— Created by Takaaki Naganoya on 2020/01/29.
— Copyright © 2020 Takaaki Naganoya. All rights reserved.
—

script AppDelegate
  
  
property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property theView : missing value
  
property DCButton : missing value
  
property aConMenu : missing value
  
  
on applicationWillFinishLaunching:aNotification
    —
  end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
on clicked:aSender
    display dialog "Clicked"
  end clicked:
  
  
on dispContextual:aEvent
    current application’s NSMenu’s popUpContextMenu:(aConMenu) withEvent:(aEvent) forView:(theView)
  end dispContextual:
  
  
on action:aSender
    display dialog (tag of aSender) as string
  end action:
  
end script

★Click Here to Open This Script 

AppleScript名:DCButton.applescript
—
— DCButton.applescript
— Kamenoko
—
— Created by Takaaki Naganoya on 2020/05/18.
— Copyright © 2020 Takaaki Naganoya. All rights reserved.
—

script DCButton
  property parent : class "NSButton"
  
  
on mouseDown:aEvent
    set buttonNum to aEvent’s buttonNumber()
    
set aEtype to aEvent’s type()
    
set aCount to aEvent’s clickCount()
    
    
if aCount = 3 then –Triple Click
      display dialog "Triple Click"
      
    else if aCount = 2 then –Double Click
      display dialog "Double Click"
      
    end if
  end mouseDown:
  
  
on mouseMoved:theEvent
    log {"mouseMoved", aEvent}
  end mouseMoved:
  
  
on mouseUp:aEvent
    log {"mouseUp", aEvent}
  end mouseUp:
  
  
on mouseDragged:aEvent
    log "mouseDragged"
  end mouseDragged:
  
  
on rightMouseDown:aEvent
    –Display Contextual Menu
    
current application’s NSApp’s delegate()’s performSelector:"dispContextual:" withObject:(aEvent)
  end rightMouseDown:
  
  
on rightMouseUp:aEvent
    log {"rightMouseUp", aEvent}
  end rightMouseUp:
  
  
on clicked:aSender
    continue clicked:(missing value)
  end clicked:
  
  
(*
  on mouseEntered:theEvent
    log {"mouseEntered", theEvent}
  end mouseEntered:

  on mouseExited:theEvent
    log {"mouseExited", theEvent}
  end mouseExited:
*)
end script

★Click Here to Open This Script 

Posted in AppleScript Application on Xcode | Tagged 10.13savvy 10.14savvy 10.15savvy NSButton NSMenu | Leave a comment

自分のウィンドウのフルスクリーン化 v2

Posted on 5月 21, 2020 by Takaaki Naganoya

Xcodeで作成したAppleScriptアプリケーションの、メインウィンドウ上のビューをフルスクリーン表示させるAppleScriptです。

→ Download Xcode Project

AppleScriptのProjectだとoptionにmissing value以外が使えないみたいなのですが、、、、

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— fullScreenTest
—
— Created by Takaaki Naganoya on 2020/05/21.
— Copyright © 2020 Takaaki Naganoya. All rights reserved.
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
property theWindowView : missing value
  
  
on applicationWillFinishLaunching:aNotification
    — Insert code here to initialize your application before any files are opened
  end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    — Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
on clicked:aSender
    set fMode to (theWindowView’s inFullScreenMode) as boolean
    
if fMode = true then
      theWindowView’s exitFullScreenModeWithOptions:(missing value)
    else
      theWindowView’s enterFullScreenMode:(current application’s NSScreen’s mainScreen()) withOptions:(missing value)
    end if
  end clicked:
end script

★Click Here to Open This Script 

Posted in AppleScript Application on Xcode | Tagged 10.14savvy 10.15savvy NSScreen NSWindow | 1 Comment

slider+buttonを作成 v5

Posted on 5月 21, 2020 by Takaaki Naganoya

スライダーをダイアログ上に表示して、ユーザーの入力を求めるAppleScriptです。


▲Script Editor上で実行


▲Script Debugger上で実行


▲Script Menu上で実行


▲Switch Control上で実行

最近はこうした箱庭ダイアログシリーズも書き方がこなれてきて、ランタイム環境に依存せずに(実際は、特定の環境で動かないということが少なくなりつつ)実行できるようになってきました。

スライダーコントロールはこうした箱庭シリーズの初期にいろいろいじくって試していたものですが、あまりに初期すぎて書き方が古いものが多かったので、最新のこなれた書き方で書き直しておきました。

ただ、スライダーコントロールが単体でダイアログ上に配置されていても、実際にハマる用途が存在せず、単なるデモンストレーションに終始してしまいそうであります。

アラートダイアログの通知メッセージ(一番大きな文字で表示される)をスライダーで変更することができなかったので、ダイアログのタイトルでスライダーの値を表示するようにしています。スライダーが必要な状況というのは、いくつかのパラメータを一緒に設定するケースが多いはずなので、やっぱり単体で設定できても意味がないような気がとてもします。

AppleScript名:slider+buttonを作成 v5
— Created 2020-5-17 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSSlider : a reference to current application’s NSSlider
property NSSplitView : a reference to current application’s NSSplitView
property NSTickMarkBelow : a reference to current application’s NSTickMarkBelow
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSScreenSaverWindowLevel : a reference to current application’s NSScreenSaverWindowLevel

property windisp : false
property wController : false
property aSliderValMSG : ""

property sliderRes : 0

set aMaxVal to 12
set aButtonMSG to "OK"
set winWidth to 400
set aSliderValMSG to "Slider Value : "

set paramObj to {myMax:aMaxVal, myBMes:aButtonMSG, mySliderMes:aSliderValMSG, myWidth:winWidth}
–my getSliderValue:paramObj
my performSelectorOnMainThread:"getSliderValue:" withObject:(paramObj) waitUntilDone:true
return sliderRes

on getSliderValue:paramObj
  set aMaxVal to (myMax of paramObj) as real
  
set aButtonMSG to (myBMes of paramObj) as string
  
set aSliderValMSG to (mySliderMes of paramObj) as string
  
set winWidth to (myWidth of paramObj) as real
  
  
set (my aSliderValMSG) to aSliderValMSG
  
  
set aView to NSSplitView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, winWidth, 40))
  
aView’s setVertical:false
  
  
–Sliderをつくる
  
set aSlider to makeSider(aMaxVal) of me
  
aView’s setSubviews:{aSlider}
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:""
    
–its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aView
    
set aWin to its |window|()
    
set bList to buttons()
  end tell
  
  
aWin’s setTitle:(my aSliderValMSG & (sliderRes as text))
  
aWin’s setLevel:NSScreenSaverWindowLevel
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
set sliderRes to (aSlider’s intValue()) as number
end getSliderValue:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on sliderChanged:aSender
  set sliderRes to aSender’s intValue()
  
set parentWin to aSender’s |window|()
  
parentWin’s setTitle:(my aSliderValMSG & (sliderRes as text))
end sliderChanged:

on makeSider(aMaxNum)
  set aSlider to NSSlider’s alloc()’s init()
  
aSlider’s setMaxValue:aMaxNum
  
aSlider’s setMinValue:1
  
aSlider’s setNumberOfTickMarks:aMaxNum
  
aSlider’s setKnobThickness:50
  
aSlider’s setAllowsTickMarkValuesOnly:true
  
aSlider’s setTickMarkPosition:(NSTickMarkBelow)
  
set sliderRes to (aMaxNum div 2)
  
aSlider’s setIntValue:sliderRes
  
aSlider’s setTarget:me
  
aSlider’s setAction:("sliderChanged:")
  
return aSlider
end makeSider

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSRunningApplication NSSlider NSSplitView | Leave a comment

InstrumentsがAppleScriptに対応

Posted on 5月 19, 2020 by Takaaki Naganoya

InstrumentsはXcodeに同梱されているメモリ使用状況などの記録、ビジュアル化を行うツールで、アクティビティモニタの強化版といったものです。

監視対象のモジュール(Instruments)を選択してドキュメント上に配置し、監視対象プロセスを選択して記録すると、動作中のプロセスの各種リソース使用状況がわかります。

そのInstrumentsがAppleScriptに対応している(sdefを持っている)ことがわかりました(調べたことがなかった)。

Dock上でXcodeのサブメニューから起動が可能です。


▲macOS 10.14.6上で動作するInstruments version 11.3.1。バージョン番号はインストールされているXcodeと同じものを名乗っているもよう

Instrumentsを使って開発中のアプリケーションのメモリ使用状況を記録して可視化(グラフを眺めるぐらい?)してみると、ダラダラ長時間記録するよりも、目的の箇所で記録を行なったほうが使い勝手がよく、Instrumentで記録した書類が複数できてきます。

それらを選択してオープンするのに、Instruments書類(単なるログ?)はファイルサイズが巨大。これをオープンするとけっこうな処理時間がかかります。Scriptから操作できたほうがよさそうだと考えて、冗談半分でAS対応していないか調べたところ、対応していると出ました。

InstrumentsのAppleScript用語辞書の内容を見てみると、ファイルのオープン/クローズができる程度で、他に何ができるというわけでもありません。

Documentの新規作成ぐらいはできそうですが、試してみたところクラッシュします。新規作成時に、どのリソースを監視するかというモジュール(Instruments)を指定する必要があるので、ドキュメント作成時にこのInstrumentsを指定できないあたりでGUI側との機能の不一致が起こっているのでしょう。

また、ドキュメントを新規作成したあとで、個別にInstrumentsを追加できるコマンドも必要になっていくことでしょう。

AppleScript名:指定書類をオープン
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/19
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

set aFile to choose file

with timeout of 3600 seconds
  tell application "Instruments"
    open aFile
  end tell
end timeout

★Click Here to Open This Script 

AppleScript名:最前面のドキュメントから情報を取得
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/19
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

tell application "Instruments"
  tell front document
    properties
    
–> {file:file "Cherry:Users:me:Documents:Instruments_withoutRetina.trace:", modified:false, name:"Instruments_withoutRetina.trace", class:document}
    
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:新規書類作成(クラッシュ)
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/19
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

tell application "Instruments"
  make new document –This command cause crash
end tell

★Click Here to Open This Script 

Posted in System | Tagged 10.14savvy 10.15savvy Instruments Xcode | Leave a comment

クリップボード内の文字種別を集計して円グラフ表示

Posted on 5月 16, 2020 by Takaaki Naganoya

クリップボード内に文字列が入っていれば、いいかえれば「文字列をコピーした状態であれば」、クリップボード内容をテキストとして取り出して文字種別ごとに集計して構成比を円グラフで表示するAppleScriptです。

# CAUTION: This script process Japanese characters. So, this script make no sense for other language users

グラフ表示部分は手抜きでGoogle Chartsを呼び出しているだけなので、Macがネットワークに接続されていない場合には表示できません。

macOS標準装備のScript Menuに入れて使っています。複数の円グラフを表示させることも可能なので、典型的な例文(新聞、論文、なろう系、技術系文章、文学作品)のグラフを一覧表示して、どの例文の使用比率に近いかといったことを見てわかるようにできそうです(やらないけど)。

ありものをただ引っ張り出してきて、Script文でつないだだけなので、オリジナルで記述した部分はほとんどありません。

とはいえ、技術的にはいろいろなハードルを乗り越えまくって動かしているものでもあります。

・メインスレッドでしか動かせないWkWebView、NSAlertをScriptから呼び出している(実行環境に左右されずに実行)
・Cocoa Scriptingを行うAppleScriptObjCをscript文でscript object化して(カプセル化して)呼び出し、再利用
・WkWebViewをdialog内に表示して、マウスオーバーでデータ内容が見えるようなインタラクティブなグラフを表示

といった、いろいろ無茶なことをやっているScriptです。ただ、すでに見慣れた光景になりつつありますけれども。

AppleScript名:クリップボード内の文字種別を集計して円グラフ表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/14
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
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 NSScreenSaverWindowLevel : a reference to current application’s NSScreenSaverWindowLevel
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

–Calc Clipboard
set aRes to clipAnaliticsMain() of clipboardInfoKit
if aRes = false then return —クリップボードが空だった(文字列的に)

set totalC to totalC of aRes

set aList to {{"文字種別", "構成比"}} & rating of aRes

set aJsonArrayStr to array2DToJSONArray(aList) of me

–Pie Chart Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<body>
<div id=\"piechart\"></div>

<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
// Load google charts
google.charts.load(’current’, {’packages’:[’corechart’]});
google.charts.setOnLoadCallback(drawChart);

// Draw the chart and set the chart values
function drawChart() {
var data = google.visualization.arrayToDataTable(%@);

// Optional; add a title and set the width and height of the chart
var options = {
is3D: true,
   ’width’:600, ’height’:400
};

// Display the chart inside the <div> element with id=\"piechart\"
var chart = new google.visualization.PieChart(document.getElementById(’piechart’));
chart.draw(data, options);
}
</script>

</body>
</html>"

set aString to current application’s NSString’s stringWithFormat_(myStr, aJsonArrayStr) as string

set paramObj to {myMessage:"文字種別構成比", mySubMessage:"クリップボードの内容を集計。文字数は" & (totalC as string) & "文字", htmlStr:aString}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 600
  
set aHeight to 450
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</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 – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
aWebView’s loadHTMLString:htmlString baseURL:(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
  
  
myWindow’s setLevel:(NSScreenSaverWindowLevel)
  
  
— 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 browseStrWebContents:

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

script clipboardInfoKit
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
property NSString : a reference to current application’s NSString
  
property NSNumber : a reference to current application’s NSNumber
  
property NSDictionary : a reference to current application’s NSDictionary
  
property NSCountedSet : a reference to current application’s NSCountedSet
  
property NSCharacterSet : a reference to current application’s NSCharacterSet
  
property NSMutableArray : a reference to current application’s NSMutableArray
  
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
  
property NSRegularExpressionSearch : a reference to current application’s NSRegularExpressionSearch
  
property NSNumberFormatterRoundUp : a reference to current application’s NSNumberFormatterRoundUp
  
property NSNumberFormatterRoundDown : a reference to current application’s NSNumberFormatterRoundDown
  
  
  
on clipAnaliticsMain()
    set cCount to 0
    
set hCount to 0
    
set kCount to 0
    
set oCount to 0
    
set tCount to 0
    
    
using terms from scripting additions
      set aStr to (the clipboard as «class utf8»)
      
if aStr = "" then
        display dialog "No text data in clipboard" buttons {"OK"} default button 1
        
return false
      end if
    end using terms from
    
    
set aRec to detectCharKindRating(aStr) of me
    
    
set cCount to cCount + (kanjiNum of aRec)
    
set hCount to hCount + (hiraganaNum of aRec)
    
set kCount to kCount + (katakanaNum of aRec)
    
set oCount to oCount + (otherNum of aRec)
    
set tCount to tCount + (totalCount of aRec)
    
    
return {rating:{{"漢字", cCount}, {"ひらがな", hCount}, {"カタカナ", kCount}, {"その他", oCount}}, totalC:tCount}
  end clipAnaliticsMain
  
  
  
  
on detectCharKindRating(aStr as string)
    set aList to NSMutableArray’s arrayWithArray:(characters of aStr)
    
set theCountedSet to NSCountedSet’s alloc()’s initWithArray:aList
    
set theEnumerator to theCountedSet’s objectEnumerator()
    
    
set cCount to 0
    
set hCount to 0
    
set kCount to 0
    
set oCount to 0
    
set totalC to length of aStr
    
    
repeat
      set aValue to theEnumerator’s nextObject()
      
if aValue is missing value then exit repeat
      
      
set aStr to aValue as string
      
set tmpCount to (theCountedSet’s countForObject:aValue)
      
      
set s1Res to chkKanji(aStr) of me
      
set s2Res to chkKatakana(aStr) of me
      
set s3Res to chkHiragana(aStr) of me
      
      
if s1Res = true then
        set cCount to cCount + tmpCount
      else if s2Res = true then
        set kCount to kCount + tmpCount
      else if s3Res = true then
        set hCount to hCount + tmpCount
      else
        set oCount to oCount + tmpCount
      end if
    end repeat
    
    
set ckRes to roundingUp((cCount / totalC) * 100, 1) of me
    
set kkRes to roundingUp((kCount / totalC) * 100, 1) of me
    
set hgRes to roundingUp((hCount / totalC) * 100, 1) of me
    
set otRes to roundingUp((oCount / totalC) * 100, 1) of me
    
    
return {kanjiNum:cCount, kanjiRating:ckRes, hiraganaNum:hCount, hiraganaRating:hgRes, katakanaNum:kCount, katakanaRating:kkRes, otherNum:oCount, otherRating:otRes, totalCount:totalC}
  end detectCharKindRating
  
  
  
on chkKanji(aChar)
    return detectCharKind(aChar, "[一-龠]") of me
  end chkKanji
  
  
on chkHiragana(aChar)
    return detectCharKind(aChar, "[ぁ-ん]") of me
  end chkHiragana
  
  
on chkKatakana(aChar)
    return detectCharKind(aChar, "[ァ-ヶ]") of me
  end chkKatakana
  
  
on detectCharKind(aChar, aPattern)
    set aChar to NSString’s stringWithString:aChar
    
set searchStr to NSString’s stringWithString:aPattern
    
set matchRes to aChar’s rangeOfString:searchStr options:(NSRegularExpressionSearch)
    
if matchRes’s location() = (current application’s NSNotFound) or (matchRes’s location() as number) > 9.99999999E+8 then
      return false
    else
      return true
    end if
  end detectCharKind
  
  
on roundingUp(aNum, aDigit as integer)
    set a to aNum as real
    
set aFormatter to NSNumberFormatter’s alloc()’s init()
    
aFormatter’s setMaximumFractionDigits:aDigit
    
aFormatter’s setRoundingMode:(NSNumberFormatterRoundUp)
    
set aStr to aFormatter’s stringFromNumber:(NSNumber’s numberWithFloat:a)
    
return (aStr as text) as real
  end roundingUp
end script

★Click Here to Open This Script 

Posted in dialog Internet JavaScript Text | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSCharacterSet NSCountedSet NSDictionary NSMutableArray NSNumber NSNumberFormatter NSNumberFormatterRoundDown NSNumberFormatterRoundUp NSRegularExpressionSearch NSRunningApplication NSScreenSaverWindowLevel NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

システムフォントをWeightつきで指定

Posted on 5月 15, 2020 by Takaaki Naganoya

システムフォントをWeightつきで指定するAppleScriptです。

NSFontまわりの、フォント名を具体的に文字列で指定「しない」フォントの指定方法を、(必要があったので)いろいろ調べてみました。

ここに紹介したサンプルでは、System FontをWeightおよびSize指定して取得していますが、本当にやりたいのは言語(英語、日本語など)とセリフつき(Timesなど)サンセリフ(Helveticaなど)、Handwritingフォントかなどの属性情報を指定すると、なんとなくフォントを特定してくれる処理で、とてもOS内にありそうな気もするのですが、まだ見つけられておりません。

AppleScript名:システムフォントをWeightつきで指定.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/14
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

set aFont1 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightRegular)
—> (NSFont) ".AppleSystemUIFont 48.00 pt. P [] (0x60000154c060) fobj=0x7f8bb176bfc0, spc=10.20"
set aFont1Name to aFont1’s fontName() as string
–> ".AppleSystemUIFont"

set aFont2 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightUltraLight)
–> (NSFont) ".AppleSystemUIFontUltraLight 48.00 pt. P [] (0x6000012d42a0) fobj=0x7f8bb8925090, spc=10.10"
set aFont2Name to aFont2’s fontName() as string
–> ".AppleSystemUIFontUltraLight"

set aFont3 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightThin)
–> (NSFont) ".AppleSystemUIFontThin 48.00 pt. P [] (0x6000013fd350) fobj=0x7f8bb3ba1140, spc=10.12"
set aFont3Name to aFont3’s fontName() as string
–> ".AppleSystemUIFontThin"

set aFont4 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightLight)
–> (NSFont) ".AppleSystemUIFontLight 48.00 pt. P [] (0x6000013fd410) fobj=0x7f8bb3bbf890, spc=10.17"
set aFont4Name to aFont4’s fontName() as string
–> ".AppleSystemUIFontLight"

set aFont5 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightMedium)
–> (NSFont) ".AppleSystemUIFontMedium 48.00 pt. P [] (0x60000151c8a0) fobj=0x7f8bb79289e0, spc=10.08"
set aFont5Name to aFont5’s fontName() as string
–> ".AppleSystemUIFontMedium"

set aFont6 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightSemibold)
–> (NSFont) ".AppleSystemUIFontDemi 48.00 pt. P [] (0x6000013fd710) fobj=0x7f8bb69ef060, spc=9.96"
set aFont6Name to aFont6’s fontName() as string
–> ".AppleSystemUIFontDemi"

set aFont7 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightBold)
–> (NSFont) ".AppleSystemUIFontBold 48.00 pt. P [] (0x600000bfa430) fobj=0x7f8bb3b55630, spc=9.84"
set aFont7Name to aFont7’s fontName() as string
–> ".AppleSystemUIFontBold"

set aFont8 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightHeavy)
–> (NSFont) ".AppleSystemUIFontHeavy 48.00 pt. P [] (0x600000898a50) fobj=0x7f8bb3b79730, spc=9.66"
set aFont8Name to aFont8’s fontName() as string
–> ".AppleSystemUIFontHeavy"

set aFont9 to current application’s NSFont’s systemFontOfSize:48 weight:(current application’s NSFontWeightBlack)
–> (NSFont) ".AppleSystemUIFontBlack 48.00 pt. P [] (0x6000015a57a0) fobj=0x7f8bb14cb330, spc=9.49"
set aFont9Name to aFont9’s fontName() as string
–> ".AppleSystemUIFontBlack"

★Click Here to Open This Script 

AppleScript名:システムフォントをWeightつきで指定(monospacedDigitSystemFont).scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/14
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

set aFont1 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightRegular)
—> (NSFont) ".SFNSText 16.00 pt. P [] (0x600001557d80) fobj=0x7f8bb7e011b0, spc=4.20"
set aFont1Name to aFont1’s fontName() as string
–> ".SFNSText"

set aFont2 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightUltraLight)
–> (NSFont) ".SFNSText-Light 16.00 pt. P [] (0x6000015e08d0) fobj=0x7f8bb8914700, spc=4.02"
set aFont2Name to aFont2’s fontName() as string
–> ".SFNSText-Light"

set aFont3 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightThin)
–> (NSFont) ".SFNSText-Light 16.00 pt. P [] (0x600000b789f0) fobj=0x7f8bb697f020, spc=4.02"
set aFont3Name to aFont3’s fontName() as string
–> ".SFNSText-Light"

set aFont4 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightLight)
–> (NSFont) ".SFNSText-Light 16.00 pt. P [] (0x6000015a3c90) fobj=0x7f8bb88c2130, spc=4.02"
set aFont4Name to aFont4’s fontName() as string
–> ".SFNSText-Light"

set aFont5 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightMedium)
–> (NSFont) ".SFNSText-Medium 16.00 pt. P [] (0x6000014667f0) fobj=0x7f8bb891bdd0, spc=4.06"
set aFont5Name to aFont5’s fontName() as string
–> ".SFNSText-Medium"

set aFont6 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightSemibold)
–> (NSFont) ".SFNSText-Semibold 16.00 pt. P [] (0x6000014b7120) fobj=0x7f8bb8866210, spc=3.95"
set aFont6Name to aFont6’s fontName() as string
–> ".SFNSText-Semibold"

set aFont7 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightBold)
–> (NSFont) ".SFNSText-Bold 16.00 pt. P [] (0x600001412dc0) fobj=0x7f8bb8920310, spc=3.81"
set aFont7Name to aFont7’s fontName() as string
–> ".SFNSText-Bold"

set aFont8 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightHeavy)
–> (NSFont) ".SFNSText-Heavy 16.00 pt. P [] (0x600001443720) fobj=0x7f8bb6cea5f0, spc=3.61"
set aFont8Name to aFont8’s fontName() as string
–> ".SFNSText-Heavy"

set aFont9 to current application’s NSFont’s monospacedDigitSystemFontOfSize:16 weight:(current application’s NSFontWeightBlack)
–> (NSFont) ".SFNSText-Heavy 16.00 pt. P [] (0x60000145b5d0) fobj=0x7f8bb6996ff0, spc=3.61"
set aFont9Name to aFont9’s fontName() as string
–> ".SFNSText-Heavy"

★Click Here to Open This Script 

Posted in Font System | Tagged 10.13savvy 10.14savvy 10.15savvy NSFont | Leave a comment

Switch Controlを起動

Posted on 5月 13, 2020 by Takaaki Naganoya

Switch Controlを起動するAppleScriptです。macOS標準搭載のScript Menuに入れて呼び出して使っています。Switch Controlは、障害者向けの支援機能を提供するmacOSの標準機能で、標準のマウス/トラックパッド、キーボードなどの利用が困難なユーザーに向けて少ないボタンや音声で操作する機能を提供するものです。

一般のユーザーにとってもSwitch Controlは有効活用できる機能であるため、個人的にいろいろ試しています。

もともと、Switch Controlを起動するためのコマンドは用意されていません。AppleScriptのコマンドで起動できるとか、コマンドラインから起動できるとかいった手軽な起動手段は存在していません。

……というわけで、仕方なくGUI Scriptingで画面上のチェックボックスをクリックするという不毛な処理を書いたわけですが、ただダラダラとGUI部品の階層をなぞるだけの知性のカケラもないコードを書くだけでは意味がありません。

この、クリックする対象のチェックボックスを実行言語環境が変わっても自動で検出できるようにチャレンジしてみました。

結果:失敗 追いかける対象が大きすぎたようです。システム環境設定の画面上のチェックボックスについているタイトル文字を特定するだけの話なのですが、システム環境設定(System Preferences.app)の各機能はプラグインで提供されており、システム環境設定のバンドル内のstringsファイルを追いかけても希望の文字列は得られません。

# このため、チェックボックスのタイトルを言語環境ごとに書き換える必要があります

では、実際に各プラグインのバンドル構造内でstringsファイルを取得することを試みたのですが、これにも失敗。それらしい文字列は得られるものの、文章すべてが1エントリに登録されているわけではないようで、stringsファイルでキーを指定すれば各ロケールごとの対象文字列が得られる……という理想的な処理はできませんでした。

今回のアプローチは技術的には失敗してしまいましたが、他の誰かが突破する日も来るかもしれません。自分のマシンのSSD内には、割とそうした「失敗作」のScriptも存在しており、そうした失敗作が別の機会の土台になることも多々あります。

仕事で作り込む必要のあるScriptであれば、スクリプトバンドル内に各言語ごとの文字列テーブルを自分で作って、localized stringでその値を引けるようにする感じでしょうか。OS側で対象箇所の文言を変更した場合には自分のテーブル側もアップデートする必要が出てきてしまいます。

本Scriptの冒頭でSwitch Controlが起動しているかどうかのチェックを行い、起動中であれば起動処理を行わないようにしています。この判定処理自体は、単体ではほぼ意味がありませんが、こうして組み合わせることで「不要な処理を行わない」ための部品として有効に活用できているといえます。

AppleScript名:Switch Controlを起動
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/13
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set aRes to launchSwitchControl() of me

on launchSwitchControl()
  if current application’s NSWorkspace’s sharedWorkspace()’s isSwitchControlEnabled() = true then return true
  
set aLoc to (current application’s NSLocale’s currentLocale()’s languageCode()) as string
  
  
–Current Language detection
  
if aLoc = "en" then
    set aStr to "Enable Switch Control" –English
  else if aLoc = "ja" then
    set aStr to "スイッチコントロールを有効にする" –Japanese
  else
    error "Make current language entry"
  end if
  
  
tell application "System Preferences"
    activate
    
tell pane id "com.apple.preference.universalaccess"
      reveal anchor "Switch"
    end tell
  end tell
  
  
set hitF to false
  
  
tell application "System Events"
    tell process "System Preferences"
      repeat 200 times
        delay 0.1
        
if (exists checkbox aStr of tab group 1 of group 1 of window 1) then
          click checkbox aStr of tab group 1 of group 1 of window 1
          
set hitF to true
          
exit repeat
        end if
      end repeat
    end tell
  end tell
  
  
tell application "System Preferences" to quit
  
return hitF
end launchSwitchControl

★Click Here to Open This Script 

Posted in GUI Scripting | Tagged 10.14savvy 10.15savvy Switch Control System Events | Leave a comment

New eBook “Switch Control with AppleScript” now on sale

Posted on 5月 12, 2020 by Takaaki Naganoya


This ebook “Switch Control with AppleScript” is a book about Switch Control. 89 pages (today). Price: JPY 3,000.

It is one of accessibility function for people with disabiulities. But it is very useful for every macOS users specially for the scripters.

Switch Control can launch AppleScript or run keyboard shortcut sequence. We can make button-based simple GUI for AppleScript. It is the easiest environent to make GUI.

This book will contain author’s sample Switch Control. It is useful and gives you a power of automation for macOS users.


▲supplement sample Switch Control Panel


▲supplement sample Switch Control Panel

Posted in news PRODUCTS | Tagged 10.14savvy 10.15savvy Switch Control | Leave a comment

面積で評価して、Keynoteのメインウィンドウのうち最大のもののItem Numberを返す

Posted on 5月 10, 2020 by Takaaki Naganoya

ウィンドウ上に複数存在するscroll areaのうち処理対象となるべきものを面積を計算することで特定するGUI Scripting系のAppleScriptです。

どーしてもGUI Scriptingでしか操作できない機能があって、それを自動化する価値があって、大幅に発生する可能性の高い労力を削減できる見込みが立ったので、一気に自動化Scriptを作成。本Scriptはその中で作成した1つの部品です。

自分が書いた処理内容は、Keynoteで作った書類の目次ページに用意した、各スライドのタイトルに実際のスライドへのリンクを付加するもの。

本来、Keynote自体のAppleScript用語辞書に標準装備されていてほしい機能です。残念ながら標準装備されていないために、自分で組む必要があったわけです。

それを作っている途中で、このメインの(Keynoteオブジェクトを配置する中央のエリア)scroll areaのIDが起動するたびに変わるという現象に直面。初期状態(インスペクタの表示状態)をそろえてもIDが変わる。たいていこうしたGUI Scriptingがらみの「怪奇現象」に直面した場合には、スクルプトエディタやアプリケーションの再起動を行えば回避できることが多いのですが、何回かためしても回避できなかったので、scroll areaの特定をID以外で行うことに。

IDが毎回(起動ごとに)変更になるので、「最大の面積を持つもの」を計算して求めるようにしてみました。

AppleScript名:面積で評価して、Keynoteのメインウィンドウのうち最大のもののItem Numberを返す
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/09
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set areaNum to getKenoteScrollAreaMax() of me

–面積で評価して、Keynoteのメインウィンドウのうち最大のもののItem Numberを返す
on getKenoteScrollAreaMax()
  tell application "System Events"
    tell process "Keynote"
      tell window 1
        set sCount to count every scroll area
        
set tmpMax to 0
        
set tmpMaxItem to 0
        
repeat with i from 1 to sCount
          tell scroll area i
            set tmpA to size
            
copy tmpA to {tmpW, tmpH}
            
set tmpArea to tmpW * tmpH
            
if tmpArea > tmpMax then
              set tmpMax to tmpArea
              
set tmpMaxItem to i
            end if
          end tell
        end repeat
      end tell
    end tell
  end tell
  
  
return tmpMaxItem
end getKenoteScrollAreaMax

★Click Here to Open This Script 

Posted in GUI Scripting | Tagged 10.13savvy 10.14savvy 10.15savvy Keynote System Events | Leave a comment

Mac Pro 2019でアプリケーションの計算結果にズレ?!

Posted on 5月 9, 2020 by Takaaki Naganoya

知り合いがMac App Storeで買ったKamenokoを、

Mac Pro 2019の一番下のモデル(+Pro Display XDR)にインストールしたところ、画面の描画がおかしいという報告を送ってくれました。


▲左:開発環境で描画したところ 右:Mac Pro 2019で描画したところ

開発環境はmacOS 10.14.6ですが、macOS 10.13.6およびmacOS 10.15.4やBeta版でも動作確認は行っていました。しかし、手元のどの環境でも、こんな結果にはなっていません。

この6角形の描画については、JavaScriptCoreを呼び出して三角関数の計算を行っています(毎回計算しているわけではなく、起動時に計算した内容をキャッシュして使っています)。この計算結果がXeonとCore i7/Core i5/Core i3で異なるのではないかという「仮説」を立てています。

また、これまでRetina(Hi-DPI)表示は2xのRetinaだったわけですが、Mac Pro 2019ではこれが違っており、描画がその影響を受けている可能性もあります(だったらウィンドウなどの描画も間違うはずなので、多分これはないかなー)。

ただ、いずれにせよMac Pro 2019実機で検証を行う環境が手元にないため、仮説の検証を行えない状態です。

MacScripter.net上で三角関数の計算結果について、同じ計算結果が得られないといった話をされたことがありますが「そんなバカな」と思っていました。もしも、その時の相手が使っていたマシンがXeon搭載機だった場合には、JavaScript Coreを呼び出して三角関数の計算を行った場合に、環境によっては結果が異なるという話になるのかも?

現段階ではなんともいえませんが、さすがにDTSにサポートを依頼すべき内容かもしれません、、、

Posted in Bug PRODUCTS | Tagged 10.15savvy | 1 Comment

アラートダイアログ上にWebViewでGoogle Chartsを表示(Calendar Chart)

Posted on 5月 7, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを配置し、Google Chartsを用いてCalendar Chartを表示するAppleScriptです。

自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で100日間のアクセス履歴を処理して7秒強ぐらいで描画が終了します。

調子に乗って300日分のアクセス履歴を処理したところ、表示まで1分ほどかかりました。あまり長い期間の描画を行わせるのは(このプログラムの書き方だと)向いていないと感じます。いまのところテストしただけで実用性は考えていませんが、この程度のグラフなら自前でNSImage上にボックスを描画して表示しても大した手間にはならないでしょう。


▲スクリプトエディタ上で実行したところ


▲Script Debugger上で実行したところ


▲スクリプトメニュー上で実行したところ

Safariのアクセス履歴は例によってsqliteのDatabaseにアクセスして取得していますが、AppleScriptのランタイム環境によっては、アクセス権限がないというメッセージが出てアクセスできないことがあります。ASObjC Explorer 4上では実行できませんでしたし、Switch Control上でも実行できません。

# 管理者権限つきで実行しても(with administrator privileges)実行できません → Switch Controlでも実行できるようになりました

最初に掲載したバージョンでは、グラフ化したときに表示月が1か月ズレるという問題がありました。

Google Chartsのドキュメントを確認したところ、

Note: JavaScript counts months starting at zero: January is 0, February is 1, and December is 11. If your calendar chart seems off by a month, this is why.

JavaScriptでMonthはJanuaryが0らしく、monthを-1する必要があるとdocumentに書かれていました。うわ、なにその仕様?(ーー;;;

AppleScript名:アラートダイアログ上にWebViewでGoogle Chartを表示(Calendar Charts)v1a.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/07
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
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

script spd
  property aRes : {}
  
property bRes : {}
end script

–Calculate Safari access frequency for (parameter days)
set (aRes of spd) to calcMain(100) of safariHistLib

set (bRes of spd) to ""
repeat with i in (aRes of spd)
  set {item1, item2, item3} to parseByDelim(theName of (contents of i), "-") of me
  
set newLine to " [ new Date(" & (item1 as string) & ", " & ((item2 – 1) as string) & ", " & (item3 as string) & "), " & (numberOfTimes of i) & "]," & (string id 10)
  
set (bRes of spd) to (bRes of spd) & newLine
end repeat

set (bRes of spd) to text 1 thru -3 of (bRes of spd)

–Pie Chart Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<head>
<div id=\"calendarchart\"></div>

<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
// Load google charts
google.charts.load(’current’, {’packages’:[’calendar’]});
google.charts.setOnLoadCallback(drawChart);

// Draw the chart and set the chart values
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: ’date’, id: ’Date’ });
dataTable.addColumn({ type: ’number’, id: ’Web Access’ });
dataTable.addRows([
  %@
]);

var chart = new google.visualization.Calendar(document.getElementById(’calendar_basic’));

var options = {
title: \"Web Activity\",
height: 350,
};

chart.draw(dataTable, options);
}
</script>
</head>
<body>
  <div id=\"calendar_basic\" style=\"width: 1000px; height: 350px;\"></div>
</body>
</html>"

set aString to current application’s NSString’s stringWithFormat_(myStr, (bRes of spd)) as string

set paramObj to {myMessage:"Calendar Chart Test", mySubMessage:"This is a simple calendar chart using google charts", htmlStr:aString}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 1000
  
set aHeight to 300
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</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 – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
aWebView’s loadHTMLString:htmlString baseURL:(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 browseStrWebContents:

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

script safariHistLib
  property parent : AppleScript
  
use scripting additions
  
use framework "Foundation"
  
  
property |NSURL| : a reference to current application’s |NSURL|
  
  
script spd
    property sList : {}
    
property nList : {}
    
property sRes : {}
    
property dRes1 : {}
    
property dRes2 : {}
  end script
  
  
  
on calcMain(daysNum)
    set (dRes1 of spd) to dumpSafariHistoryFromDaysBefore(daysNum) of me
    
    
set (dRes2 of spd) to {}
    
repeat with i in (dRes1 of spd)
      copy (first item of i) as string to dStr
      
set convDstr to first item of (parseByDelim(dStr, {" "}) of me)
      
set the end of (dRes2 of spd) to convDstr
    end repeat
    
    
–日付ごとに登場頻度集計
    
set cRes to countItemsByItsAppearance2((dRes2 of spd)) of me
    
return cRes as list
  end calcMain
  
  
  
–NSArrayに入れたレコードを、指定の属性ラベルの値でソート
  
on sortRecListByLabel(aArray, aLabelStr as string, ascendF as boolean)
    –ソート
    
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
    
set sortDescArray to current application’s NSArray’s arrayWithObjects:sortDesc
    
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
    
    
–NSArrayからListに型変換して返す
    
set bList to (sortedArray) as list
    
return bList
  end sortRecListByLabel
  
  
  
on dumpSafariHistoryFromDaysBefore(daysBefore)
    –現在日時のn日前を求める
    
using terms from scripting additions
      set origDate to (current date) – (daysBefore * days)
    end using terms from
    
    
set dStr to convDateObjToStrWithFormat(origDate, "yyyy-MM-dd hh:mm:ss") of me
    
    
set aDBpath to "~/Library/Safari/History.db"
    
set pathString to current application’s NSString’s stringWithString:aDBpath
    
set newPath to pathString’s stringByExpandingTildeInPath()
    
    
set aText to "/usr/bin/sqlite3 " & newPath & " ’SELECT datetime(history_visits.visit_time+978307200, \"unixepoch\", \"localtime\"), history_visits.title || \" @ \" || substr(history_items.URL,1,max(length(history_items.URL)*(instr(history_items.URL,\" & \")=0),instr(history_items.URL,\" & \"))) as Info FROM history_visits INNER JOIN history_items ON history_items.id = history_visits.history_item where history_visits.visit_time>(julianday(\"" & dStr & "\")*86400-211845068000) ORDER BY visit_time ASC LIMIT 999999;’"
    
    
using terms from scripting additions
      set (sRes of spd) to do shell script aText
    end using terms from
    
    
set (sList of spd) to (paragraphs of (sRes of spd))
    
    
repeat with i in (sList of spd)
      set j to contents of i
      
      
–Parse each field
      
set j2 to parseByDelim(j, {"|", "@ "}) of me
      
      
set the end of (nList of spd) to j2
    end repeat
    
    
return (nList of spd)
  end dumpSafariHistoryFromDaysBefore
  
  
  
  
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
  
  
  
–出現回数で集計
  
on countItemsByItsAppearance2(aList)
    set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
    
set bArray to current application’s NSMutableArray’s array()
    
set theEnumerator to aSet’s objectEnumerator()
    
    
repeat
      set aValue to theEnumerator’s nextObject()
      
if aValue is missing value then exit repeat
      
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"})
    end repeat
    
    
–出現回数(numberOfTimes)で降順ソート
    
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"theName" ascending:true
    
bArray’s sortUsingDescriptors:{theDesc}
    
    
return bArray
  end countItemsByItsAppearance2
  
  
  
on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string)
    set aDF to current application’s NSDateFormatter’s alloc()’s init()
    
    
set aLoc to current application’s NSLocale’s currentLocale()
    
set aLocStr to (aLoc’s localeIdentifier()) as string
    
    
aDF’s setLocale:(current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr)
    
aDF’s setDateFormat:aFormatStr
    
set dRes to (aDF’s stringFromDate:aDateO) as string
    
return dRes
  end convDateObjToStrWithFormat
  
end script

★Click Here to Open This Script 

Posted in JavaScript shell script Sort | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding Safari WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

指定アプリケーションを指定言語環境で再起動 v3

Posted on 5月 6, 2020 by Takaaki Naganoya

指定アプリケーションを、現在のユーザーアカウントで指定可能な言語環境を指定して再起動するAppleScriptの改良版です。

初版では言語環境を選んでからアプリケーションを選んでいましたが、この順番を逆にしました。アプリケーションを選択し、そのバンドル内のローカライズ状況を調べ、一覧から選択して起動します。


▲最初にアプリケーションを選択


▲Keynoteのローカライズ言語一覧から対象言語コードを選択


▲アラビア語環境で起動させたKeynote


▲タイ語環境で起動させたKeynote


▲ロシア語環境で起動させたKeynote


▲中国語(簡体字)環境で起動させたKeynote

個人的には割と実用性が高いScriptです。

AppleScript名:指定アプリケーションの指定言語環境で再起動 v3.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/06
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSBundle : a reference to current application’s NSBundle
property NSWorkspace : a reference to current application’s NSWorkspace

set anApp to path to (choose application)

tell application "Finder"
  set aBundle to properties of anApp
  
set targID to id of aBundle –Get Bundle ID
end tell

set bRes to getLocalizationsFromBundleID(targID) of me
set cRes to my sort1DList:bRes ascOrder:true

set dRes to (choose from list cRes)
if dRes = missing value or dRes = false then return

set targLanguage to first item of dRes

set appPath to retPathFromBundleID(targID) of me

set sText to "open -n -a " & quoted form of appPath & " –args -AppleLanguages ’(\"" & targLanguage & "\")’"
do shell script sText

on getLocalizationsFromBundleID(aBundleID)
  set aRes to retPathFromBundleID(aBundleID) of me
  
if aRes = false then error "Wrong Bundle ID."
  
return getSpecifiedAppFilesLocalizationListWithDuplication(aRes) of me
end getLocalizationsFromBundleID

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を許容
on getSpecifiedAppFilesLocalizationListWithDuplication(appPOSIXpath)
  set aURL to (|NSURL|’s fileURLWithPath:appPOSIXpath)
  
set aBundle to NSBundle’s bundleWithURL:aURL
  
set locList to aBundle’s localizations()
  
return locList as list
end getSpecifiedAppFilesLocalizationListWithDuplication

on retPathFromBundleID(aBundleID)
  set aURL to NSWorkspace’s sharedWorkspace()’s URLForApplicationWithBundleIdentifier:aBundleID
  
if aURL = missing value then return false –Error
  
return aURL’s |path|() as string
end retPathFromBundleID

–1D Listをsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DList:theList ascOrder:aBool
  set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"self" ascending:aBool selector:"localizedCaseInsensitiveCompare:"
  
set theArray to current application’s NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DList:ascOrder:

★Click Here to Open This Script 

Posted in Locale | Tagged 10.13savvy 10.14savvy 10.15savvy Finder NSBundle NSURL NSWorkspace | Leave a comment

Keynoteのselectionの使い方が判明

Posted on 5月 4, 2020 by Takaaki Naganoya

AppleScriptにおける「selection」という予約語は割と重要で、選択中のオブジェクトや選択中のテキストを特定したり、選択中のオブジェクトへの処理を行うといった、一歩踏み出した処理が行えます。

KeynoteのAppleScript用語辞書に「selection」が追加されたのは、2019年3月にリリースされたv9.0のこと。

「list of iWork item」を返してくると記載されていることから、スライド(ページ)上で選択中の各種iWork item(shapeとかimageとかtext itemなどの各種オブジェクト)の選択状態を取得できることが期待されたわけですが、実際に試してみるとAppleScript用語辞書のようにiWork itemsを取得できるわけではありませんでした(当時のガッカリ感が半端ない)。

ところが、些細なことからこのKeynoteのselectionが「何を」選択しているかを返すかが分かってきました。

この、ウィンドウ左側のアウトライン表示されている各スライド(ページ)。ここを複数選択した状態でselectionを実行すると、このスライドがlistで返ってくることがわかりました。

この動作を知らずに(KeynoteのAppleScriptの用語辞書を信用して)試すと、現在表示中のスライド(ページ)のオブジェクトがリストで返ってくるという動作になります。なので、このselectionは現在表示中のスライド(ページ)のオブジェクトを返す(超使えない)コマンドだと判断していました。

ウィンドウ内容の表示ポップアップから「Light Table」を選択すると、

各スライドのサムネールが一覧表示されますが、

ここで複数スライドを選択しても「selection」で選択状態を取得できるわけではないようです。

Keynoteに対するAppleScriptの処理で、スライド上の各種オブジェクトの位置やサイズを統一するようなものがありますが、そういう範囲で使うのであれば有効に使えるといったところでしょうか。

Posted in list | Tagged 10.14savvy 10.15savvy Keynote | Leave a comment

Early access program : ebook “Switch Control with AppleScript”

Posted on 5月 4, 2020 by Takaaki Naganoya


This is an early access program. This ebook is in progress, not finished. The early access reader can read it with agreement. The early access readers can make request to author during works (every request will be discussed, without 100% guarantee to be realized). 65 pages (today). Price: JPY 3,000.

This ebook “Switch Control with AppleScript” is a book about Switch Control. It is one of accessibility function for people with disabiulities. But it is very useful for every macOS users specially for the scripters.

Switch Control can launch AppleScript or run keyboard shortcut sequence. We can make button-based simple GUI for AppleScript. It is the easiest environent to make GUI.

This book will contain author’s sample Switch Control. It is useful and gives you a power of automation for macOS users.

Posted in PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy Switch Control | Leave a comment

Switch Controlがオンになっているか調べる

Posted on 5月 3, 2020 by Takaaki Naganoya

Switch Controlが起動中かどうかをNSWorkspace経由で調べるAppleScriptです。

いろいろなAppleScriptをSwitch Controlのパネルに盛り込んで利用していますが、けっこう使いでがあっていい感じです。Script MenuにAppleScriptを入れて呼び出すのも実用性が高くてよいのですが、Switch Controlのパネルに入れると常時フローティングパネルで表示される(消したり最小化も可)ため、アプリケーションの機能が不完全であると感じるところをユーザーが自分で勝手に補える感覚がとてもいい感じです。

ただ、1つ問題があるとすれば、Switch Controlをプログラム側から起動する方法が公開されていないようである点。本Scriptのように、起動中であることを判定する方法は提供されているのですが。

Switch Control(=AssistiveControl)がオンになっていると、InputManager側から見えるので

このあたりに解決の鍵がありそうな気もします。ただ、文字入力に介在できる機能でもあるため、セキュリティ上の懸念から「あえて」そうしたAPIを公開していないのかも。

現状では唯一、GUI Scriptingで野蛮にチェックボックスをクリックするか、あるいいはチェックボックスの値を変更するぐらいでしょう。実際に試してはいないので、これもできるか100%の保証があるものではありませんけれども。

AppleScript名:スイッチコントロールがオンになっているか調べる.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/01/02
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

current application’s NSWorkspace’s sharedWorkspace()’s isSwitchControlEnabled()
–> true / false

★Click Here to Open This Script 

Posted in System | Tagged 10.13savvy 10.14savvy 10.15savvy NSWorkspace Switch Control | Leave a comment

Kamenoko、Mac App Storeで販売開始

Posted on 5月 3, 2020 by Takaaki Naganoya

Mac App Storeでリジェクトをくらうこと3回。ようやくKamenokoがMac App Storeで販売開始になりました。本アプリケーションは、Piyomaru SoftwareがAppleScriptで開発し、Mac App Storeで販売したアプリケーションの2作品目になります。

# Mac App Storeからちゃんと買えることを確認しました。こういうの、1つ1つ確認しないと怖いです

1つやらかしたのは、検索キーワードにアプリケーション名を入れておかなかったので、アプリケーション名で検索できないという「お可愛らしい」ミス。

些細な機能のアップデートをリリースしてキーワードを追加しておくほかなさそうです。

# v1.1のリリース時にいろいろ宣伝を(人力で)行うことにします。このv1.1で安定性と速度が大幅に向上し(このあたりはプログラム以外の要素による)、簡易Undoや入力ダイアログの文字化け抑止など、完成度が大幅に増しています。Mac Pro 2019で計算間違いが起こる現象についても対処を行なっています(実機がないので検証は行えないんですけれども)

最初のバージョンなので、メニューなどは日本語ローカライズしていません。

また、中身がほぼ99.9%AppleScriptで書いてあるものの、

Scriptableではありません。このアプリケーションの特性からいって、アプリケーションの書類を操作(読み書き)できるAppleScriptライブラリをアプリケーションバンドル内に入れることで、アプリケーション自体をScriptableにしなくても書類を操作できてよいのではないかと考えています。

主要機能をコンテクストメニューから呼び出すので、ワンボタンマウスを使うと手も足も出ません。その点のみ要注意です。

本アプリケーションで苦労した点

もともと、この6角形の図形を使ってKeynote上でいろいろアイデアを練ったり説明のための図を作っていろいろ試してみたら「この図を作るアプリケーションは便利だし、自分でも作れそうだ」と思いついたのがきっかけです。


▲LGやPanasonicが出している透明有機ELディスプレイに表示させるとこんな感じに?(想像図)

ハリウッド映画に出てくるハリウッド的な未来風のインタフェースを実際に実装してみるとこんな感じになるだろうか、というコンセプトでデザインしています。


▲Panasonic様のショールームを訪問して、実機で表示してみたところ

透明ディスプレイでは、明暗差を大きく確保しないとオブジェクトの視認性が下がるとか、グラデーション表現を行うと視認性が下がるといった「仮説」を立て、なるべく一色でベタ塗りするように味付けしています。このあたりは、透明ディスプレイに合わせたチューニングです。グリーンバック表示機能も、どの程度使えるか不明ですが、黒色バック透過モードで使い勝手がよくなかった場合への備えでもあります(一説には、黒色バック透過が一番きれいに透過するもよう)。

濃い色を積極的に使っているのも、透明ディスプレイの透過モード時には全体的に白っぽく表示される傾向があるようなので、「白飛び」を避けることが目的です。

1月中旬ぐらいに作り始め、1月末には初期バージョンが動いていました。


▲初期バージョン


▲セルのダブルクリックで文字入力が可能に(2月中旬)


▲指定セル内キーワードのタクソノミー展開を実装(2月中旬)


▲ビューの拡大・縮小表示、コンテクストメニュー表示が可能に(2月末)


▲ブロック認識、ブロック削除が可能に(3月中旬)


▲AirDrop共有、データ埋め込みPNG書き出し(3月中旬)


▲テーマセレクタが完成(3月下旬)


▲大型文字入力ダイアログを追加(4月)

正直なところ、こんなストロングスタイルのGUIアプリケーションを作ろうと思ったことはなかったので、いろいろと未知の現象に直面しました。

一番真っ青になったのは、開発途上でド派手なメモリリークに直面したときです。たいていのAppleScriptアプリケーションは、まとまった処理を行うためのパラメータ選択をGUI画面上で行い、メイン処理が動いたらまとまった処理を行って終了という動き方をするものでした。つまり、GUIアプリケーションといいつつもメモリリークに苦しめられることが少なかったのです。

こんな風にユーザーと対話動作をたえず行い、結果をグラフィックとして画面に描画する(=メモリリークの危険性の高い)アプリケーションを作るのははじめてです。

まずは、些細な処理でWindow Serverのメモリを大量に消費してクラッシュするという現象に直面。開発初期にこの現象の対策が行えたことはラッキーでした(Edama2さんにはこの段階でいろいろ助言をいただきました)。

次に、プレビュー作成時にメモリリークを行う現象に直面。いくぶん緩和していますが、ここは解決できていません。クラッシュしても、作業中の内容を定期的に保存し、強制終了後の再起動時にデータをリカバリする機能を追加。クラッシュしにくくする方向の努力はしつつも、クラッシュしてもデータを失いにくい方向に機能強化しました。

環境設定まわりの機能はけっこう実装に苦労しています。実装が間に合わなかったので、仕様的には幾分日和りました。

そして、毎度毎度のことながらSandbox化には苦しみました。コード署名するのに、Mac App Installerの署名とMac App IDの署名があり、間違ってMac App Installerで署名したり。あとは、コマンドラインから起動するタイプのツールをアプリケーションバンドル内に同梱して呼び出していたのですが(display mirror)、コードサインで問題が出たので分離せずにアプリケーション内に組み込むように変更しました(リジェクトされている間に機能改変)。

本アプリケーションでプログラム的に一番苦労したのは、ブロック認識プログラムです。データ上の1つの塊をまとめて処理するのに、この独特のヘックス構造のコマのせいで、前例がないような独創的な処理をいろいろと書かなくてはなりませんでした。

作りたかったけどv1.0にはあきらめた機能 ほか

アルファテスターからの指摘もありましたが、Undoがないのはけっこう辛いです。結局、Undoの実装のためには内部データを改変のたびに時系列順に保存し、保存した最新-1の状態に戻すといった実装になると思います。この、無段階Undoを実装することは可能と思われましたが、割と大掛かりな機能になりそうな(1か月ぐらいかかりそう)気配がしたので初版では見送りました。

本アプリケーションはScriptableではありません。将来的には、書類の読み取りと変更を行う機能を持つScript Libraryを同梱する方向でAppleScript対応を考えています(たぶん、これが一番楽で実用的)。

キャンバスの回転機能は単体で動くものが出来上がっていますが、まだアプリケーションに組み込んで動作させるところまでは行っていません。

「2つのキーワードの共通要素をリストアップする」プログラムはこのKamenokoの部品用に作ったもので、単体ではそれなりに有用な部品ではあるものの、本アプリケーションにどのように組み込むかのいいアイデアが出ませんでした。データとして処理すると有用さがわかるものの、それをどのように可視化するかが課題です(多すぎるアイデアにつぶされない戦い)。

本アプリケーションには検索機能が実装されていません。検索系の部品として、類義語展開したうえで検索を行う「スタークエリー」という部品をAppleScriptで作ってあるので、組み込むとしたらこれだと(指定のキーワードだけでなく、類義語でもヒットする)思っているのですが、英語+日本語の類義語(シソーラス)辞書が200MBぐらいあるのとGUI的にどうやってヒット状況を表示するかのアイデアがなかったので実装を見送りました。あとから考えると200MBぐらい昨今のアプリケーションでは問題ではないレベルなので、悩む必要はなかったようです。

開発中はフォントメニューのキャッシュ機能を有効にしていましたが、リリース版ではこれをオフにしました。Kamenokoを起動していない間にフォントの変更(追加、削除)が行われたことを検出する方法が思いつかなかったので、フォントメニューのキャッシュが危険に思われたためです。フォントパネルを表示させてフォントを指定する方法も試してみたものの、あまりピンとこなかったので使いませんでした。

目下、メインScriptが3,000行を超えるぐらいのサイズで、全体では5,000行ぐらいは行っていると思います。メンテナンス性があまりよくないので、機能追加を行うためにはメイン部分のスリム化が必須な状況でしょう。

Posted in PRODUCTS | Tagged 10.13savvy 10.14savvy 10.15savvy Kamenoko | Leave a comment

Post navigation

  • Older posts
  • Newer posts

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AppleScriptによる並列処理
  • macOS 15でも変化したText to Speech環境
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • デフォルトインストールされたフォント名を取得するAppleScript
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • macOS 15 リモートApple Eventsにバグ?
  • Script Debuggerの開発と販売が2025年に終了
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • NSObjectのクラス名を取得 v2.1
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • 有害ではなくなっていたSpaces
  • AVSpeechSynthesizerで読み上げテスト

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (195) 14.0savvy (148) 15.0savvy (137) CotEditor (66) Finder (51) Keynote (119) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (55) Pixelmator Pro (20) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • date
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • process
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2025年7月
  • 2025年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC