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

カテゴリー: Web Contents Control

YouTubeムービー再生実験 v2c

Posted on 11月 14 by Takaaki Naganoya

メイン環境をmacOS 26にアップデートしたところ、display youtubeライブラリが動作しなくなっていたので、対処のために作った試作品の改良版です。

# 2a→2bで機能に関係ない範囲の微修正をしました
# 2b→2cでレスポンシブルモードで表示するようにHTML部分を変更しました

edama2さんからYouTubeムービー再生用の改良Scriptを送っていただいて、なんで動かなくなっていたのかの理由がわかりました。HTMLを文字列で与えるのは、問題ないものの……リファラーを「https://www.youtube.com」ではなく「https://www.google.com」にする必要があったのだとか(検索エンジンの検索結果から表示できるように、という話に見えます)。

結局、local web serverを起動する必要はなかったので起動せず、起動していないのでkillもせず、htmlの書き出しも行わないのでファイルの削除もせず、かなりシンプルな内容に戻りましたし、ダイアログ表示と同時にYouTubeムービーの再生を開始する機能も復活。

Thanks!>edama2氏

AppleScript名:YouTubeムービー再生実験 v2c.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/11/13
–  Modified by edama2 & Takaaki Naganoya on: 2025/11/13
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8"
use framework "Cocoa"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property WKWebView : a reference to current application’s WKWebView
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 WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration

property returnCode : 0

set mainMessage to "Youtube Test"
set subMessage to "Simple YouTube Player"
set viewSizeArray to {1280, 720}
set vId to "GP_tVXTYdmY"
set startSec to 32

set htmlString to "<body style=’background-color:red;overflow:hidden;margin:auto 0;padding:auto 0;’><div id=’ytplayer’></div>
<script>
var tag=document.createElement(’script’);
tag.src=’https://www.youtube.com/player_api’;
var firstScriptTag=document.getElementsByTagName(’script’)[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {player = new YT.Player(’ytplayer’,{height:’100%’,width:’100%’,videoId:’"
& vId & "’,playerVars:{autoplay:1,mute:0,start:" & (startSec as string) & "}});}
</script>"

set paramObj to {myMessage:mainMessage, mySubMessage:subMessage, viewSize:viewSizeArray, myHTML:htmlString}
–my browseURLContents:paramObj–For Debug with Script Editor
my performSelectorOnMainThread:"browseURLContents:" withObject:(paramObj) waitUntilDone:true

— WKWebView表示用ハンドラ
on browseURLContents:paramObj
  set webSize to viewSize of paramObj
  
copy webSize to {aWidth, aHeight}
  
set htmlString to myHTML of paramObj
  
  
set idConf to current application’s WKWebViewConfiguration’s new()
  
set aWebView to current application’s WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:idConf
  
set baseURL to (current application’s NSURL’s URLWithString:"https://www.google.com/")
  
aWebView’s loadHTMLString:htmlString baseURL:baseURL
  
  
— アラートに埋め込む
  
set theAlert to current application’s NSAlert’s new()
  
tell theAlert
    –addButtonWithTitle_("Cancel")
    
its setMessageText:(myMessage of paramObj)
    
its setInformativeText:(mySubMessage of paramObj)
    
its addButtonWithTitle:"OK"
    
its setAccessoryView:aWebView
    
set myWindow to its |window|
    
tell myWindow
      its setLevel:(current application’s NSScreenSaverWindowLevel)
      
setInitialFirstResponder_(aWebView)
    end tell
  end tell
  
  
— モーダル表示
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
set returnCode to (theAlert’s runModal()) as number
  
  
— WKWebViewの後始末
  
aWebView’s loadHTMLString:"" baseURL:(missing value)
end browseURLContents:

★Click Here to Open This Script 

Posted in dialog Web Contents Control | Tagged 26.0savvy | Leave a comment

YouTubeムービー再生実験

Posted on 11月 13 by Takaaki Naganoya

macOS 26上でdisplay youtube AppleScriptライブラリの機能を利用したAppleScriptを、macOS標準搭載の「スクリプトメニュー」から呼び出すと、

のようにエラー表示されるようになっていました。

macOS 26.0βのときには再生されたりしていたのですが、リリース後のmacOS 26.2では再生されません。

これが、macOSの内部機能やポリシーの変更によるものなのか、あるいはmacOS 26のデフォルト設定の変化によるものかは不明です。YouTube側の仕様変更という疑いもありますが、定かではありません。

以前は文字列で組み立てたHTMLをWkWebViewに読み込ませていましたが、いまmacOS 26上ではそのやり方ではYouTubeのムービーは再生されません。

そこで、根本的な解決を図るため、local web server(httpd)を介してHTMLを表示する方式に変更。docrootをtemporary items folderに設定したhttpdを起動。temporary items folderに書き込んだhtmlをダイアログ上のWkWebViewに表示するようにしました。

このlocal web serverの起動にpython3を呼び出しており、インストールされていない環境(一般的な環境ではインストールされていない)ではDeveloper Toolsのインストールが実行初回時に行われます。一般ユーザーのことを考えるとPython3以外のツールを使って起動すべきなんでしょう。

以前のバージョンと異なるのは、ダイアログ上のWkWebViewに再生用のUI(中央にYouTUbeロゴ)が配置され、それをクリックしないとムービーの再生が始まらないことです。このあたりは、自動再生を開始できるように改変できそうではあるものの、同時にデメリット(音声の再生が行えないとか)が生じるおそれがあるため、現状のままがよさそうです。

それでも、macOS 26上でWkWebViewでYouTubeムービーを再生させられるようになりました。まだ、繰り返し実行して問題が出ないかといったテストを行なっている段階です。

htmlファイルの書き込みが間に合わないと上記のようなエラーが出ていましたが、処理の冒頭で明示的にhttpdをkillすることで、この問題を解消できるようになりました。httpdのkillについては、他のプログラムが起動していた場合には問題になりそうなので、そこも様子見といったところでしょう。

ちなみに、YouTubeムービー再生以外の用途では、とくにこのような大幅な改変は必要ではないと認識しています。たとえば、CDN上のJavaScriptライブラリを呼び出してアニメーション表示つきのグラフ表示をAppleScriptで行なっていますが、こちらでは書き換えは必要ありませんでした。

AppleScript名:youtubeムービー再生実験.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2025/11/12
—
–  Copyright © 2025 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.8"
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property WKWebView : a reference to current application’s WKWebView
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 WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration

property returnCode : 0

set mainMessage to "Youtube Test"
set subMessage to "Using local Web Server"
set viewSizeArray to {1200, 640}

set youtubeMovieID to "GP_tVXTYdmY"

–テスト用HTML文字列
–set htmlString to "<!DOCTYPE html><html><body><h1>Hello World</h1></body></html>"

— HTML文字列
set htmlString to "
<!DOCTYPE html>
<html lang=\"ja\">
<head>
<meta charset=\"UTF-8\">
<title>YouTube Embed</title>
<style>
body { margin:0; padding:0; }
iframe { width:100%; height:100vh; border:none; }
</style>
</head>
<body>
<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/"
& youtubeMovieID & "?start=1\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>
</body>
</html>
"

try
  do shell script "pkill -f ’http.server’ || true"
end try

set docroot to POSIX path of (path to temporary items)

–1. Python3でバックグラウンドサーバー起動(Local Web Server)
set pythonCmd to "python3 -m http.server 8000 –directory " & quoted form of docroot & " >/dev/null 2>&1 & echo $!"
set pidStr to do shell script pythonCmd
set serverPID to pidStr as integer

— 2. HTMLを書き出す
set htmlPath to docroot & "index.html"
set nsHTML to current application’s NSString’s stringWithString:htmlString
nsHTML’s writeToFile:htmlPath atomically:true encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)

— 3. 少し待ってサーバー起動を待機
delay 0.5

try
  — 4. WKWebViewでHTTP URLを読み込む
  
set httpURL to "http://localhost:8000/index.html"
  
set paramObj to {myMessage:mainMessage, mySubMessage:subMessage, viewSize:viewSizeArray, htmlStr:"", myURL:httpURL}
  
  
–my browseURLContents:paramObj
  
my performSelectorOnMainThread:"browseURLContents:" withObject:(paramObj) waitUntilDone:true
on error errMsg
  display dialog errMsg
end try

— 5. サーバープロセス終了
try
  do shell script "pkill -f ’http.server’ || true"
end try

— WKWebView表示用ハンドラ
on browseURLContents:paramObj
  set webSize to viewSize of paramObj
  
copy webSize to {aWidth, aHeight}
  
  
set aURL to myURL of paramObj
  
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
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
  
  
set bURL to |NSURL|’s URLWithString:aURL
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
— Move to frontmost
  
current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular)
  
current application’s NSApp’s activateIgnoringOtherApps:true
  
  
— アラートに埋め込む
  
set theAlert to current application’s NSAlert’s alloc()’s init()
  
tell theAlert
    –addButtonWithTitle_("Cancel")
    
its setMessageText:(myMessage of paramObj)
    
its setInformativeText:(mySubMessage of paramObj)
    
its addButtonWithTitle:"OK"
    
its setAccessoryView:aWebView
    
set myWindow to its |window|
    
tell myWindow
      its setLevel:(current application’s NSScreenSaverWindowLevel)
      
setInitialFirstResponder_(aWebView)
    end tell
  end tell
  
  
— モーダル表示
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
set returnCode to (theAlert’s runModal()) as number
  
  
— WKWebViewの後始末
  
set jsStop to "try { document.getElementById(’ytplayer’).contentWindow.postMessage(’{\"event\":\"command\",\"func\":\"stopVideo\",\"args\":\"\"}’, ’*’); } catch(e) {}"
  
aWebView’s evaluateJavaScript:jsStop completionHandler:(missing value)
  
delay 0.1
  
aWebView’s loadRequest:(NSURLRequest’s requestWithURL:(|NSURL|’s URLWithString:"about:blank"))
  
delay 0.1
  
aWebView’s stopLoading()
  
set aWebView to missing value
  
  
set aWebView to missing value
end browseURLContents:

★Click Here to Open This Script 

Posted in dialog Web Contents Control | Tagged 26.0savvy | Leave a comment

アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v4

Posted on 12月 6, 2024 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを作成して、さまざまなグラフや3Dアニメーションを表示してきた「箱庭ダイアログ」の1つの到達点、「periodictable」(元素周期表)選択UIの表示デモAppleScriptです。

–> Download Script Bundle

実行は掲載リストではなく上記のリンクからダウンロードした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

★Click Here to Open This Script 

Posted in 3D Animation Web Contents Control | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

アラートダイアログ上にWkWebViewでGoogle Chartsを表示 v2

Posted on 4月 29, 2020 by Takaaki Naganoya

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

自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で10日間のアクセス履歴を処理して1.38秒程度でダイアログ表示してグラフ描画に入ります。3秒強ぐらいで描画が終了します。

WkWebViewに対して、文字列で組み立てたHTMLを読み込んでグラフ表示しています。Pie Chart上にマウスカーソルを乗せると反応します。一応表示できているぐらいで、デザイン的には余計な余白ができたままで、いまひとつな感じです。せめて、WkWebViewの背景を透明化できると大味な表示をいくらか緩和できるかと思っているのですが、WkWebViewの透明背景にはNSColorではなく(AppleScriptから作成できない)CGColorでclearColor(透明色)を指定する必要があるようで、、、、

サンプル表示データは、Safariの10日間のアクセス履歴からドメイン単位で計算したヒストグラムを、その場で計算したものを使っています。

本Scriptは、①NSAlertのダイアログ表示の経験 ②WkWebView上へのコンテンツ表示の経験 ③グラフ表示用FrameworkやSVGベースのグラフ作成の経験 を経て、2・3年越しで完成したものです。とくに、WkWebViewについてはサンプル数がそれほど多くなく、用途の方向性がObjective-CやSwiftと若干異なるために、参考にできるサンプルの数が多くない状況。必然的に、いろいろ試しては失敗を重ねてきました。急に出来上がってきたものではありません。

Safariの履歴集計ScriptをScriptオブジェクトの中に放り込んだら、scripting additionsの用語をusing terms from句で囲っておく必要がありました。何回か経験していますが、知らないと対処に困る現象です。

現状(macOS 10.14以降)では、Scripting AdditionはmacOS標準搭載のStandard Additionsしか存在していないし認識も行われないため、エラー内容がいまひとつわかりにくく、不正確であるように思えます。Apple純正のStandard Additionsしか存在していないんだから自分で判断しろやコラ、と言いたくなります。

AppleScript名:アラートダイアログ上にWebViewでGoogle Chartを表示 v2.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 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

–Calc Safari access domain from history
set aRes to calcSafariHistoryBest10Domain(10) of safariHistoryLib

set aList to {{"Domain", "Access"}}
repeat with i in aRes
  set aDom to theName of i
  
set accessNum to numberOfTimes of i
  
set the end of aList to {aDom, accessNum}
end repeat

–set aList to {{"Task", "Hours per Day"}, {"Work", 8}, {"Eat", 2}, {"TV", 4}, {"Gym", 2}, {"Sleep", 8}}

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 = {’title’:’’, ’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:"Pie Chart Test", mySubMessage:"This is a simple pie 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 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
  
  
— 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

–Safariのn日前からの履歴をドメイン別に集計してソート
script safariHistoryLib
  use scripting additions
  
use framework "Foundation"
  
property parent : AppleScript
  
  
property |NSURL| : a reference to current application’s |NSURL|
  
  
script spd
    property sList : {}
    
property nList : {}
    
property sRes : {}
  end script
  
  
  
on calcSafariHistoryBest10Domain(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 "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))
    
    
set (nList of spd) to {}
    
    
repeat with i in (sList of spd)
      set j to contents of i
      
      
–Parse each field
      
set j2 to parseByDelim(j, {"|", "@ "}) of me
      
      
–Calculate URL’s domain only
      
set j3 to contents of last item of j2
      
set aURL to (|NSURL|’s URLWithString:j3)
      
      
if aURL = missing value then
        set j4 to ""
      else
        set j4 to (aURL’s |host|()) as string
      end if
      
      
set the end of (nList of spd) to j4
    end repeat
    
    
–登場頻度でURLを集計
    
set aList to countItemsByItsAppearance((nList of spd)) of me
    
    
    
–Best 10の計算のために10位以下をまとめる
    
set best9 to items 1 thru 9 of aList
    
set best10 to items 10 thru -1 of aList
    
    
set otherTimes to 0
    
repeat with i in best10
      set otherTimes to otherTimes + (numberOfTimes of i)
    end repeat
    
    
set the end of best9 to {theName:"Other", numberOfTimes:otherTimes}
    
return best9
  end calcSafariHistoryBest10Domain
  
  
  
  
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 countItemsByItsAppearance(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:"numberOfTimes" ascending:false
    
bArray’s sortUsingDescriptors:{theDesc}
    
    
return bArray as list
  end countItemsByItsAppearance
  
  
  
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 dialog Web Contents Control | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding Safari WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | 1 Comment

コンテンツ中の表示中のエリア座標を取得する

Posted on 9月 18, 2019 by Takaaki Naganoya

Safariで表示中のWebコンテンツの表示範囲の座標を取得するAppleScriptです。

Webブラウザに対するAppleScriptの処理といえば、

 (1)表示中のURLを取得して処理
 (2)表示中のコンテンツにJavaScriptを実行したりGUI Scripting経由で操作(特定要素をカウントしたりFormに値を入れたりボタンを押したり)
 (3)表示中のHTMLソースを取得して処理
 (4)Webブラウザそのものの環境情報(Bookmarkや履歴など)にアクセスして処理
 (5)選択中のテキストを取得して処理
 (6)テキストを選択しておいて、その内容が該当する要素を抽出

といった操作を行ってきました。

(1)は、Webブラウザで表示中のURLを他のプログラムで処理する場合などに便利な、基礎的な処理です。
(2)は、ロボット的なScriptにありがちな、メニューの奥深く(URLで一発オープンが無理なログインを要求される構造のWebサイトとか)にあるデータを定期的に取得するような処理によく使います。
(3)は、(1)の延長線上にあるもので、HTMLReaderなどのHTMLそのものを解釈して処理できる高機能フレームワークと組み合わせてWebスクレイピングを行うものです
(4)は、書いてあるとおりブックマークや履歴などにアクセスして統計処理を行なったりしています。
(5)は、ちょっとした調べ物や翻訳などを行いたい場合に使っています。
(6)は、(3)の処理を行いたいが、処理対象の要素(表など)が複数あるので、どの要素なのか特定するための補助情報としてテキスト選択を要求するものです。

このうち、(6)に該当する処理が現状だといまひとつです。Webブラウザ上でテキストを選択しておく必要があるというのでは使い勝手がよくありません。

Webコンテンツのうち、Webブラウザ上で表示中の要素を取得するようなやり方であれば、その方が使い勝手がよいことでしょう。Wikipedia上の表データを使いまわしたいが、対象ページ上に表が複数あるので、いま現在Webブラウザのウィンドウ上で見えている範囲内に存在する表を取り出すようにすれば、より気の利いた処理になることでしょう。

AppleScript名:コンテンツ中の表示中のエリア座標を取得する
–https://stackoverflow.com/questions/9271747/can-i-detect-the-user-viewable-area-on-the-browser
tell application "Safari"
  set dCount to count every document
  
if dCount = 0 then return
  
  
set aHeight to do JavaScript "window.innerHeight;" in front document
  
set sHeight to do JavaScript "window.scrollY;" in front document
  
  
set aWidth to do JavaScript "window.innerWidth;" in front document
  
set sWidth to do JavaScript "window.scrollX;" in front document
  
  
return {myWidth:aWidth, scrollX:sWidth, myHeight:aHeight, scrollY:sHeight}
end tell

★Click Here to Open This Script 

Posted in JavaScript Web Contents Control | Tagged 10.12savvy 10.13savvy 10.14savvy Safari | Leave a comment

YouTubeムービーの状態を取得、操作

Posted on 2月 16, 2019 by Takaaki Naganoya

Safari上で表示中のYouTubeのムービーの再生状態を取得、再生/停止のトグル動作を行うなどのAppleScriptです。

追記(2021/7/31):pausedの属性を取得できていないですね。YouTube側に変更があったのか…?
追記(2022/1/21):YouTube側の仕様がかわって、ムービープレイヤーに対する操作が通りません。x倍速再生が便利だったのですが…

macOS標準搭載のスクリプトメニューに入れて呼び出しています。

AppleScript名:Safariの最前面のウィンドウで再生中のYouTubeムービーの状態を取得する
–Get YouTube Movie status
tell application "Safari"
  tell front document
    set aRes to (do JavaScript "document.querySelector(’#movie_player video’).paused;")
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:Safariの最前面のウィンドウで再生中のYouTubeムービーを再生_停止をトグル切り替え
–Toggle Youtube play/pause
tell application "Safari"
  tell front document
    set aRes to (do JavaScript "document.querySelector(’#movie_player .ytp-play-button’).click();")
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:Safariの最前面のウィンドウでオープン中のYouTubeムービーを再生
tell application "Safari"
  tell front document
    set aURL to URL
    
–最前面のウィンドウがYouTubeの場合のみ処理
    
if aURL begins with "https://www.youtube.com/" then
      set aRes to (do JavaScript "document.querySelector(’#movie_player video’).paused;")
      
if aRes = true then
        –停止中(一時停止中)の場合のみ再生操作
        (
do JavaScript "document.querySelector(’#movie_player .ytp-play-button’).click();")
      end if
    end if
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:Safariの最前面のウィンドウでオープン中のYouTubeムービーの再生フレームの冒頭からの時間を取得
tell application "Safari"
  tell front document
    set aURL to URL
    
–最前面のウィンドウがYouTubeの場合のみ処理
    
if aURL begins with "https://www.youtube.com/" then
      set tRes to (do JavaScript "document.querySelector(’#movie_player video’).getCurrentTime();")
    end if
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:Safariの最前面のウィンドウでオープン中のYouTubeムービーの再生ポジションを変更
tell application "Safari"
  tell front document
    set aURL to URL
    
–最前面のウィンドウがYouTubeの場合のみ処理
    
if aURL begins with "https://www.youtube.com/" then
      set tRes to (do JavaScript "document.querySelector(’#movie_player video’).currentTime =300;")
    end if
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:Safariの最前面のウィンドウでオープン中のYouTubeムービーのdurationを取得
tell application "Safari"
  tell front document
    set aURL to URL
    
–最前面のウィンドウがYouTubeの場合のみ処理
    
if aURL begins with "https://www.youtube.com/" then
      set tRes to (do JavaScript "document.querySelector(’#movie_player video’).duration;")
    end if
  end tell
end tell

★Click Here to Open This Script 

Posted in JavaScript URL Web Contents Control | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy Safari | 3 Comments

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

Google Search

Popular posts

  • Numbersで選択範囲のセルの前後の空白を削除
  • macOS 26, Tahoe
  • KagiのWebブラウザ、Orion
  • Script Debuggerの開発と販売が2025年に終了
  • 【続報】macOS 15.5で特定ファイル名パターンのfileをaliasにcastすると100%クラッシュするバグ
  • macOS 15 リモートApple Eventsにバグ?
  • NSObjectのクラス名を取得 v2.1
  • macOS 15:スクリプトエディタのAppleScript用語辞書を確認できない
  • 2024年に書いた価値あるAppleScript
  • Xcode上のAppleScriptObjCのプログラムから、Xcodeのログ欄へのメッセージ出力を実行
  • (確認中)AppleScript Dropletのバグっぽい動作が解消?
  • AppleScript Dropletのバグっぽい動作が「復活」(macOS 15.5β)
  • macOS 26, 15.5でShortcuts.app「AppleScriptを実行」アクションのバグが修正される
  • Numbersで選択中の2列のセルを比較して並べ直して書き戻す v2
  • Script Debuggerがフリーダウンロードで提供されることに
  • 指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップ
  • Apple、macOS標準搭載アプリ「写真」のバージョン表記を間違える
  • 執筆中:AppleScript最新リファレンスver2.8対応(macOS 15対応アップデート)
  • macOS 15.5beta5(24F74)でaliasのキャスティングバグが修正された???
  • Keynoteで選択中のtext itemの冒頭のフォントを太くする v2

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (204) 14.0savvy (159) 15.0savvy (158) 26.0savvy (23) CotEditor (66) Finder (52) 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 (56) 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
  • Newt On Project
  • 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
  • Scripting Additions
  • 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年11月
  • 2025年10月
  • 2025年9月
  • 2025年8月
  • 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