master
p3ls 2020-10-24 21:37:49 +02:00
commit 4044c23905
38 changed files with 2877 additions and 0 deletions

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# Tastenkürzel
Neuer Workspace
ctrl + shift + N
Neues Fenster
ctrl + shift + W
Fenster hinzufügen
ctrl + shift + A
Workspace Öffnen
ctrl + shift + O
Workspace Schliessen
ctrl + shift + Q
Workspace Speichern
ctrl + shift + S

1
Services Symbolic link
View File

@ -0,0 +1 @@
/Users/stef/Library/Services

32
add-window.js Normal file
View File

@ -0,0 +1,32 @@
var workspace = Library("workspace")
var name = workspace.chooseFromList("Add Window")
if(name){
var title = workspace.chooseFromSafariWindows()
console.log(title)
var id = workspace.safariWindowWithTitle(title)
console.log(id)
workspace.addWindowToWorkspace(id, name)
}
// var docs = Application('Safari').documents
// for (var i = 0; i < docs.length; i++) {
// Things[i]
// }
// Application('Safari').documents[1].name()
// var app = Application('Safari')
// var windows = app.windows()
// for (var k = 0; k < windows.length; k++) {
// var url = app.windows.at(k).currentTab.url()
// var name = app.windows.at(k).currentTab.name()
// var id = app.windows.at(k).id()
// console.log(url, name)
// }

8
add.js Normal file
View File

@ -0,0 +1,8 @@
var workspace = Library("workspace")
var name = workspace.chooseFromList("Add New Window")
if(name){
workspace.addNewWindowTo(name)
}

38
build.sh Executable file
View File

@ -0,0 +1,38 @@
#!/bin/sh
# cli.sh
# workspace open Elm
# workspace print Elm
# workspace save Elm
# bash_completions
osacompile -l JavaScript -o "$HOME/Library/Script Libraries/os.scpt" os.js
osacompile -l JavaScript -o "$HOME/Library/Script Libraries/workspace.scpt" workspace.js
# echo "Libraries copied $HOME/Library/Script Libraries"
if [ "$1" = "" ]; then
echo "usage: build.sh open|close|add|new|workflow" && exit 0
fi
if [ "$1" = "workflow" ]; then
cp -r "workflows/New Workspace.workflow" "$HOME/Library/Services"
cp -r "workflows/New Window in Workspace.workflow" "$HOME/Library/Services"
cp -r "workflows/Open Workspace.workflow" "$HOME/Library/Services"
cp -r "workflows/Close Workspace.workflow" "$HOME/Library/Services"
cp -r "workflows/Save Workspace.workflow" "$HOME/Library/Services"
exit 0
fi
if [ -f "$1.js" ]; then
osascript -l JavaScript "$1.js"
else
echo "error: $1.js not found" && exit 1
fi

7
close.js Normal file
View File

@ -0,0 +1,7 @@
var workspace = Library("workspace")
var name = workspace.chooseFromList("Close Workspace")
if(name){
workspace.closeWindows(name)
}

31
new.js Normal file
View File

@ -0,0 +1,31 @@
var workspace = Library("workspace")
var app = Application.currentApplication()
app.includeStandardAdditions = true
var response = app.displayDialog("Enter New Workspace Name", {
defaultAnswer: "",
withIcon: "note",
buttons: ["Cancel", "Continue"],
defaultButton: "Continue"
})
var selectedWorkspaceName = response.textReturned
var allWorkspaceNames = workspace.getNames()
for (var i = 0; i < allWorkspaceNames.length; i++) {
if(allWorkspaceNames[i] == selectedWorkspaceName){
var response = app.displayDialog(" Workspace name already used. Please choose another", {
defaultAnswer: "",
withIcon: "note"
})
}
}
var selectedWorkspaceProps = { Safari: [] }
workspace.saveProperties(selectedWorkspaceName, selectedWorkspaceProps)
workspace.addNewWindowTo(selectedWorkspaceName)
// Result: {"buttonReturned":"Continue", "textReturned":"Jen"}
// app.displayDialog("Hello, " + (response.textReturned) + ".")

7
open.js Normal file
View File

@ -0,0 +1,7 @@
var workspace = Library("workspace")
var name = workspace.chooseFromList("Open workspace")
if(name){
workspace.openWindows(name)
}

78
os.js Normal file
View File

@ -0,0 +1,78 @@
ObjC.import('Foundation')
ObjC.import('AppKit')
/**
*
* Get environment variable by name
*
*/
function env(name){
var env = $.NSProcessInfo.processInfo.environment // -[[NSProcessInfo processInfo] environment]
env = ObjC.unwrap(env)
for (var k in env) {
if(k == name){
return ObjC.unwrap(env[k])
}
}
return undefined
}
function readJson(path) {
var data = readFile(path)
if(!data[0]){ return [false, "file error"] }
try{
var obj = JSON.parse(data[1])
}catch(err){
return [false, "JSON error"]
}
return [true, obj]
}
function readFile(file) {
var app = Application.currentApplication()
app.includeStandardAdditions = true
// Convert the file to a string
var fileString = file.toString()
try{
var p = Path(fileString)
}catch(err){ return [false, err] }
try{
var str = app.read(p)
}catch(err){
return [false, err]
}
// Read the file and return its contents
return [true, str]
}
function writeFile(pPathStr, pOutputStr) {
var nsStr = $.NSString.alloc.initWithUTF8String(pOutputStr)
var nsPath = $(pPathStr).stringByStandardizingPath
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + pPathStr)
}
return successBool
}
function writeJson(path, obj) {
try{
var str = JSON.stringify(obj, null, 2)
}catch(err){ return [false, "JSON error"]}
try{
writeFile(path, str)
}catch(err){
return [false, "file error"]
}
return [true, obj]
}

1
safari-workspaces Symbolic link
View File

@ -0,0 +1 @@
/Users/stef/.safari-workspaces

9
save.js Normal file
View File

@ -0,0 +1,9 @@
var workspace = Library("workspace")
var name = workspace.chooseFromList("Save Workspace")
if(name){
workspace.saveWindows(name, workspace.readProperties(name))
}
// workspace.saveWindows("CouchDB", workspace.readProperties("CouchDB"))

View File

@ -0,0 +1,54 @@
var currentApp = Application.currentApplication();
currentApp.includeStandardAdditions = true;
var finder = Application("Finder");
var systemEvents = Application("System Events");
// Ask a folder to process
var sourcePath = currentApp.chooseFolder ({
withPrompt: "Choose the source folder"
}).toString();
var sourceFolder = systemEvents.aliases.byName(sourcePath);
// Create the destination folder
var container = sourceFolder.container();
var containerPath = container.path();
var destinationFolder = finder.make({
new: "folder", at: containerPath,
withProperties: { name: sourceFolder.name() + " - Edited" }
});
// Create an array of items to be processed
var items = systemEvents.aliases.byName(sourcePath).diskItems;
var selectedItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.class() != "folder" && item.visible()) {
selectedItems.push(item.name());
}
}
// Process every item
var createdFolders = [];
selectedItems.forEach(function(itemName) {
var item = systemEvents.aliases.byName(sourcePath + "/" + itemName);
var name = item.name().match(/(.*) - (.*)/);
try {
var folderName = name[1];
if (!createdFolders.includes(folderName)) {
var newFolder = finder.make({
new: "folder", at: destinationFolder, withProperties: { name: folderName }
});
createdFolders.push(folderName);
}
item = finder.move(item.path(), { to: destinationFolder.folders[folderName] });
item.name = name[2];
} catch (error) {
console.log("Error (item: " + item.name() + "): " + error);
}
});

178
trash/add.js Normal file
View File

@ -0,0 +1,178 @@
var systemEvents = Application("System Events");
var workspacesDir = "/Users/stef/dbox/src/safari-workspace/workspaces"
function getWorkspaceNames() {
var items = systemEvents.aliases.byName(path).diskItems;
var selectedItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.class() != "folder" && item.visible()) {
selectedItems.push(item.name().substring(0, item.name().length - 5));
}
}
return selectedItems;
}
function chooseWorkspaceFromList() {
var app = Application.currentApplication()
app.includeStandardAdditions = true
var choices = getWorkspaceNames()
var choice = app.chooseFromList(choices, {
withPrompt: "Workspace wählen:",
defaultItems: [0]
})
return choice
}
function allWindows(){
var app = Application("Safari")
var windows = []
for(var i = 0; i < app.windows().length; i++){
windows.push(app.windows.at(i).id())
}
return windows
// return windows.sort(function(a, b){return a-b})
}
function newWindow(){
var app = Application("Safari")
app.activate()
app.Document().make()
delay(1)
return newWindowID(-1)
}
function newWindowID(index){
var app = Application("Safari")
var windows = allWindows()
if(index < 0){
index = windows.length + index
}
return app.windows.byId(windows[index]).id()
}
function readJson(path) {
var data = readFile(path)
if(!data[0]){ return [false, "file error"] }
try{
var obj = JSON.parse(data[1])
}catch(err){
return [false, "JSON error"]
}
return [true, obj]
}
function readFile(file) {
var app = Application.currentApplication()
app.includeStandardAdditions = true
// Convert the file to a string
var fileString = file.toString()
try{
var p = Path(fileString)
}catch(err){ return [false, err] }
try{
var str = app.read(p)
}catch(err){
return [false, err]
}
// Read the file and return its contents
return [true, str]
}
function writeFile(pPathStr, pOutputStr) {
var nsStr = $.NSString.alloc.initWithUTF8String(pOutputStr)
var nsPath = $(pPathStr).stringByStandardizingPath
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + pPathStr)
}
return successBool
}
function writeJson(path, obj) {
try{
var str = JSON.stringify(obj, null, 2)
}catch(err){ return [false, "JSON error"]}
try{
writeFile(path, str)
}catch(err){
return [false, "file error"]
}
return [true, obj]
}
function setWorkspaceProperties(workspaceName, workspaceProps) {
var path = workspacesDir + "/" + workspaceName + ".json"
var result = writeJson(path, selectedWorkspaceProps)
var success = result[0]
return success
}
function getWorkspaceProperties(workspaceName) {
var result = readJson(workspacesDir + "/" + workspaceName + ".json")
if(result[0]){
return result[1]
}
return {error: "workspace not found"}
}
function newWorkspaceWindow(workspaceProps) {
var winID = newWindow()
var win = {id: winID, tabs: []}
workspaceProps["Safari"].push(win)
// add tab
// selectedWorkspaceProps["Safari"][0]["tabs"].push("http://example.com")
}
function saveWorkspaceWindows() {
var app = Application("Safari")
// var windows = []
for(var i = 0; i < app.windows().length; i++){
for (var j = 0; j < selectedWorkspaceProps["Safari"].length; j++) {
var workspaceWinID = selectedWorkspaceProps["Safari"][j].id
console.log(workspaceWinID, app.windows.at(i).id())
// if(workspaceWinID == app.windows.at(i).id()){
// }
}
// windows.push(app.windows.at(i).id())
}
}
// var selectedWorkspaceName = chooseWorkspaceFromList()
var selectedWorkspaceName = "needle"
var selectedWorkspaceProps = getWorkspaceProperties(selectedWorkspaceName)
newWorkspaceWindow(selectedWorkspaceProps)
setWorkspaceProperties(selectedWorkspaceName, selectedWorkspaceProps)
saveWorkspaceWindows()
// console.log(JSON.stringify(selectedWorkspaceProps, null, 2))
// console.log()

38
trash/choose.js Normal file
View File

@ -0,0 +1,38 @@
var systemEvents = Application("System Events");
function getWorkspaceNames() {
var path = "/Users/stef/dbox/src/safari-workspace/workspaces"
var items = systemEvents.aliases.byName(path).diskItems;
var selectedItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.class() != "folder" && item.visible()) {
selectedItems.push(item.name().substring(0, item.name().length - 5));
}
}
return selectedItems;
}
function chooseWorkspaceFromList() {
var app = Application.currentApplication()
app.includeStandardAdditions = true
var choices = getWorkspaceNames()
var choice = app.chooseFromList(choices, {
withPrompt: "Workspace wählen:",
defaultItems: [0]
})
return choice
}
console.log(chooseWorkspaceFromList())

10
trash/folder.js Normal file
View File

@ -0,0 +1,10 @@
var app = Application.currentApplication()
app.includeStandardAdditions = true
function readFile(file) {
// Convert the file to a string
var fileString = file.toString()
// Read the file and return its contents
return app.read(Path(fileString))
}

75
trash/run.js Normal file
View File

@ -0,0 +1,75 @@
var app = Application("Safari")
function newWorkspaceWindow(){
app.activate()
app.Document().make()
// delay(1)
// return window id
return newWindowID()
}
function newWindowID(){
var windows = getAllWindows()
if(index < 0){
index = windows.length + index
}
return app.windows.byId(windows[index]).id()
}
/**
@returns {Array} List of objects in the form {title: title, url:url}
*/
function tabsInWindowWithId(id){
var urls = []
if(!sys.windowExistWithId("Safari", id)){
return urls
}
var win = app.windows.byId(id)
for (var i = 0; i < win.tabs.length; i++) {
var url = win.tabs.at(i).url()
var name = win.tabs.at(i).name()
urls.push({name:name, url:url})
}
return urls
}
function getAllWindows(){
var windows = []
for(var i = 0; i < app.windows().length; i++){
windows.push(app.windows.at(i).id())
}
return windows
// return windows.sort(function(a, b){return a-b})
}
function tabsInWindowAtIndex(index) {
var win
for(var i = 0; i < app.windows().length; i++){
if(i == index){
win = app.windows.at(i)
}
}
var tabs = []
for (var i = 0; i < win.tabs.length; i++) {
var url = win.tabs.at(i).url()
var title = win.tabs.at(i).name()
tabs.push({title: title, url: url})
}
return tabs
}
var tabs = tabsInWindowAtIndex(0)
for (var i = 0; i < tabs.length; i++) {
console.log(tabs[i].title, tabs[i].url)
}
// console.log(getAllWindows())
// console.log(newWorkspaceWindow())

224
trash/safari.js Normal file
View File

@ -0,0 +1,224 @@
#!/usr/bin/env osascript -l JavaScript
var sys = Library("system")
var app = Application('Safari')
var workspace
function setWorkspace(w){
workspace = w
sys.setWorkspace(w)
}
function create(url){
app.Document().make().url = url
delay(1)
return sys.windowID("Safari", -1)
}
/**
@desc Get list of workspace-related windows from file. If there
are stored windows that do not exist, they will be removed.
@param {String} appName
@returns {Array} List of objects in the form {id:2445, }
*/
function workspaceWindows() {
var result = sys.retrieve("Safari")
var success = result[0]
var wlist = result[1]
if(!success){
return []
}
return wlist
}
// var url = "https://news.ycombinator.com/"
// var name = "HN"
// var id = safari.create(url)
// console.log("id", id)
// if(id != -1){
// var workspaceWindow = {id:id, url:url, name:name }
// wlist.push(workspaceWindow)
// if(store(appName, wlist)[0]){
// return true
// }
// }
function addWorkspaceWindow(){
var wlist = workspaceWindows()
var name = "HN"
var url = "https://news.ycombinator.com/"
var id = create(url)
if(id != -1){
var workspaceWindow = {id:id, tabs:[{url:url, name:name}] }
wlist.push(workspaceWindow)
if(sys.store("Safari", wlist)[0]){
return true
}
}
return false
}
function deleteWorkspaceWindow() {
list()
var index = parseInt(sys.prompt("The window at which index would you delete?", -1))
if (index < 0){
return false
}
var wlist = workspaceWindows()
console.log("list", wlist.length, "index", index)
if(wlist.length > index){
var win = wlist[index]
var id = win["id"]
console.log("win", JSON.stringify(win))
if(sys.windowExistWithId("Safari", id)){
app.close(app.windows.byId(id))
}
wlist.splice(index, 1)
sys.store("Safari", wlist)
}else{
console.log("out of range")
}
}
/**
@desc Print list of all open Terminal windows.
**/
function list() {
var wlist = workspaceWindows()
for (var i = 0; i < wlist.length; i++) {
var id = wlist[i]["id"]
var running = sys.windowExistWithId("Safari", id)
var winName = ""
var tabCount = wlist[i]["tabs"].length
var win = null
if(running){
win = app.windows.byId(id)
winName = win.name()
tabCount = win.tabs.length + 1
}
console.log(i, id, "tabs", tabCount, "running", running , winName)
}
}
function addTab(id, url){
var tab = app.Tab()
tab.url = url
var win = app.windows.byId(id)
win.tabs.push(tab)
}
function open(){
var wlist = workspaceWindows()
var changed = false
// define new window if none are there
if(wlist.length == 0){
var win
var url = arguments[0]
if(arguments.length > 0){
win = {id:0, tabs:[{name:"", url:url}]}
}else{
win = {id:0, tabs:[{name:"HN", url:"http://news.ycombinator.com"}]}
}
wlist.push(win)
changed = true
}
// create windows
for (var i = 0; i < wlist.length; i++) {
var win = wlist[i]
var id = win.id
if(!sys.windowExistWithId("Safari", id)){
var tabs = wlist[i]["tabs"]
var windowID = create(tabs[0]["url"])
wlist[i]["id"] = windowID // update window id in file
changed = true
for (var j = 1; j < tabs.length; j++) {
if(tabs[j]["url"] != null){
addTab(windowID, tabs[j]["url"])
}
}
}
}
if(changed){
sys.store("Safari", wlist)
}
return true
}
function save(wlist){
if(wlist.length == 0) return false
for (var i = 0; i < wlist.length; i++) {
var win = wlist[i]
var id = win.id
if(sys.windowExistWithId("Safari", id)){
var tabs = tabsInWindowWithId(id)
if(tabs.length > 0){
wlist[i]["tabs"] = tabs
}
}
}
return sys.store("Safari", wlist)[0]
}
function close(){
var wlist = workspaceWindows()
if(wlist.length == 0) return false
if(!save(wlist)){
console.log("safari window save error")
}
for (var i = 0; i < wlist.length; i++) {
try{
// var win = wlist[i]
// var id = win.id
// console.log("close", JSON.stringify(wlist[i]))
app.close(app.windows.byId(wlist[i]["id"]))
}catch(err){}
}
return true
}
/**
@returns {Array} List of objects in the form {url:url, name:name}
*/
function tabsInWindowWithId(id){
var urls = []
if(!sys.windowExistWithId("Safari", id)){
return urls
}
var win = app.windows.byId(id)
for (var i = 0; i < win.tabs.length; i++) {
var url = win.tabs.at(i).url()
var name = win.tabs.at(i).name()
urls.push({name:name, url:url})
}
return urls
}

320
trash/save.js Normal file
View File

@ -0,0 +1,320 @@
var systemEvents = Application("System Events");
var workspace = Library("workspace")
// return
var workspacesDir = "/Users/stef/dbox/src/safari-workspace/workspaces"
var app = Application("Safari")
// var selectedWorkspaceName = "needle"
// var selectedWorkspaceName = chooseWorkspaceFromList()
// var selectedWorkspaceProps = getWorkspaceProperties(selectedWorkspaceName)
// console.log(JSON.stringify(selectedWorkspaceProps, null, 2))
// New Workspace...
// New Workspace Window...
// Open Workspace...
// Close Workspace...
// Save Workspace...
// workspace.js
// system.js
// close.js
// save.js
// open.js
// new.js
// window.js
function getWorkspaceNames() {
var items = systemEvents.aliases.byName(path).diskItems;
var selectedItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.class() != "folder" && item.visible()) {
selectedItems.push(item.name().substring(0, item.name().length - 5));
}
}
return selectedItems;
}
function chooseWorkspaceFromList() {
var app = Application.currentApplication()
app.includeStandardAdditions = true
var choices = getWorkspaceNames()
var choice = app.chooseFromList(choices, {
withPrompt: "Workspace wählen:",
defaultItems: [0]
})
return choice
}
function allWindows(){
var app = Application("Safari")
var windows = []
for(var i = 0; i < app.windows().length; i++){
windows.push(app.windows.at(i).id())
}
// return windows
return windows.sort(function(a, b){return a-b})
}
function newWindow(){
var app = Application("Safari")
app.activate()
app.Document().make()
console.log(app.windows().length)
// delay(1)
// console.log(app.windows().length)
var windows = allWindows()
return windows[windows.length - 1]
}
function newWindowID(index){
var app = Application("Safari")
var windows = allWindows()
if(index < 0){
index = windows.length + index
}
return app.windows.byId(windows[index]).id()
}
function readJson(path) {
var data = readFile(path)
if(!data[0]){ return [false, "file error"] }
try{
var obj = JSON.parse(data[1])
}catch(err){
return [false, "JSON error"]
}
return [true, obj]
}
function readFile(file) {
var app = Application.currentApplication()
app.includeStandardAdditions = true
// Convert the file to a string
var fileString = file.toString()
try{
var p = Path(fileString)
}catch(err){ return [false, err] }
try{
var str = app.read(p)
}catch(err){
return [false, err]
}
// Read the file and return its contents
return [true, str]
}
function writeFile(pPathStr, pOutputStr) {
var nsStr = $.NSString.alloc.initWithUTF8String(pOutputStr)
var nsPath = $(pPathStr).stringByStandardizingPath
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + pPathStr)
}
return successBool
}
function writeJson(path, obj) {
try{
var str = JSON.stringify(obj, null, 2)
}catch(err){ return [false, "JSON error"]}
try{
writeFile(path, str)
}catch(err){
return [false, "file error"]
}
return [true, obj]
}
function saveWorkspaceProperties(workspaceName, workspaceProps) {
var path = workspacesDir + "/" + workspaceName + ".json"
var result = writeJson(path, selectedWorkspaceProps)
var success = result[0]
return success
}
function getWorkspaceProperties(workspaceName) {
var result = readJson(workspacesDir + "/" + workspaceName + ".json")
if(result[0]){
return result[1]
}
return {error: "workspace not found"}
}
function newWorkspaceWindow(workspaceProps) {
var winID = newWindow()
var win = {id: winID, tabs: []}
workspaceProps["Safari"].push(win)
}
function tabsInWindowWithId(id){
var urls = []
if(!sys.windowExistWithId("Safari", id)){
return urls
}
var win = app.windows.byId(id)
for (var i = 0; i < win.tabs.length; i++) {
var url = win.tabs.at(i).url()
var name = win.tabs.at(i).name()
urls.push({name:name, url:url})
}
return urls
}
function saveWorkspaceWindows() {
var app = Application("Safari")
for(var i = 0; i < app.windows().length; i++){
var openWindow = app.windows.at(i)
// console.log("Safari window", openWindow.id())
for (var j = 0; j < selectedWorkspaceProps["Safari"].length; j++) {
var workspaceWindow = selectedWorkspaceProps["Safari"][j]
// console.log("workspaceWindow.id", workspaceWindow.id)
if(openWindow.id() == workspaceWindow.id){
workspaceWindow.tabs = []
for (var k = 0; k < app.windows.at(i).tabs.length; k++) {
var url = openWindow.tabs.at(k).url()
if(url){
workspaceWindow.tabs.push(url)
}
}
}
}
}
saveWorkspaceProperties(selectedWorkspaceName, selectedWorkspaceProps)
}
function closeWorkspaceWindows() {
saveWorkspaceWindows()
var app = Application("Safari")
for (var i = 0; i < selectedWorkspaceProps["Safari"].length; i++) {
var workspaceWindow = selectedWorkspaceProps["Safari"][i]
for(var j = 0; j < app.windows().length; j++){
var openWindow = app.windows.at(j)
if(openWindow.id() == workspaceWindow.id){
app.close(app.windows.byId(openWindow.id()))
}
}
}
// for(var i = 0; i < app.windows().length; i++){
// var openWindow = app.windows.at(i)
// console.log("Safari window", openWindow.id())
// for (var j = 0; j < selectedWorkspaceProps["Safari"].length; j++) {
// var workspaceWindow = selectedWorkspaceProps["Safari"][j]
// console.log("workspaceWindow.id", workspaceWindow.id)
// if(openWindow.id() == workspaceWindow.id){
// app.close(app.windows.byId(openWindow.id()))
// }
// }
// }
}
function addTab(id, url){
var app = Application("Safari")
var tab = app.Tab()
tab.url = url
var win = app.windows.byId(id)
win.tabs.push(tab)
}
function openWorkspaceWindows() {
var app = Application("Safari")
for (var i = 0; i < selectedWorkspaceProps["Safari"].length; i++) {
var workspaceWindow = selectedWorkspaceProps["Safari"][i]
var windowExists = false
for(var j = 0; j < app.windows().length; j++){
var openWindow = app.windows.at(j)
if(openWindow.id() == workspaceWindow.id){
windowExists = true
}
}
if(!windowExists){
var newWindowID = newWindow()
// console.log("new window created", newWindowID)
workspaceWindow.id = newWindowID
for (var k = 0; k < workspaceWindow.tabs.length; k++) {
// console.log(workspaceWindow.tabs[k])
addTab(newWindowID, workspaceWindow.tabs[k])
}
}else{
console.log("window exists", workspaceWindow.id)
}
saveWorkspaceProperties(selectedWorkspaceName, selectedWorkspaceProps)
}
}
// console.log(allWindows())
// newWorkspaceWindow(selectedWorkspaceProps)
// setWorkspaceProperties(selectedWorkspaceName, selectedWorkspaceProps)
// console.log(allWindows())
// openWorkspaceWindows()
// closeWorkspaceWindows()
// console.log(app.windows().length)
// saveWorkspaceWindows()
var selectedWorkspaceName = workspace.chooseFromList()
// workspace.openWindows(selectedWorkspaceName)
workspace.closeWindows(selectedWorkspaceName)
// console.log(JSON.stringify(selectedWorkspaceProps, null, 2))

495
trash/system.js Normal file
View File

@ -0,0 +1,495 @@
#!/usr/bin/env osascript -l JavaScript
/**
* @fileOverview Various system functions.
*/
ObjC.import('Foundation')
ObjC.import('AppKit')
var sys_events = Application("System Events")
var workspace
function setWorkspace(w){
workspace = w
}
function workspaceHome(){
return env("WORKSPACES_HOME") + "/" + workspace
}
function workspacesHome(){
return env("WORKSPACES_HOME")
}
function test(){
console.log("workspace name", workspace["name"])
}
function sh(cmd) {
var me = Application.currentApplication()
me.includeStandardAdditions = true
me.doShellScript(cmd)
}
// More keycodes can be added. Keycode reference:
// http://www.codemacs.com/coding/applescript/applescript-key-codes-reference.8288271.htm
var key_codes = {
"→": 124,
"←": 123,
"↑": 126,
"↓": 125,
"⏎": 36
}
var modifiers = {
"⌘": "command down",
"^": "control down",
"⌥": "option down",
"⇧": "shift down"
}
function running() {
var apps = $.NSWorkspace.sharedWorkspace.runningApplications // Note these never take () unless they have arguments
apps = ObjC.unwrap(apps) // Unwrap the NSArray instance to a normal JS array
var app
for (var i = 0, j = apps.length; i < j; i++) {
app = apps[i]
console.log(ObjC.unwrap(app.bundleIdentifier))
// Another option for comparison is to unwrap app.bundleIdentifier
// ObjC.unwrap(app.bundleIdentifier) === 'org.whatever.Name'
// Some applications do not have a bundleIdentifier as an NSString
// if (typeof app.bundleIdentifier.isEqualToString === 'undefined') {
// continue;
// }
// if (app.bundleIdentifier.isEqualToString('com.apple.iTunes')) {
// isRunning = true;
// break;
// }
}
}
function press(hotkey) {
var using = [];
while (hotkey.length > 1) {
if (modifiers[hotkey[0]] == undefined) {
throw new Error(hotkey[0] + " is not a recognized modifier key");
}
using.push(modifiers[hotkey[0]]);
hotkey = hotkey.slice(1);
}
if (key_codes[hotkey] != undefined) {
sys_events.keyCode(key_codes[hotkey], {using: using});
}
else {
sys_events.keystroke(hotkey.toLowerCase(), {using: using});
}
}
function type(text) {
for (var i=0; i < text.length; i++) {
sys_events.keystroke(text[i]);
}
}
function menu_item() {
if (!arguments.length) return;
var process = sys_events.processes.whose({"frontmost": true})[0];
var menu_bar = process.menuBars[0].menuBarItems[arguments[0]];
var menu_item = menu_bar;
for (var i=1; i < arguments.length; i++) {
menu_item = menu_item.menus[0].menuItems[arguments[i]];
}
menu_item.click();
}
function quit(name) {
try{
Application(name).quit()
}catch(err){}
}
function closeWindows(name){
var app = Application(name);
for(var i = 0; i < app.windows().length; i++){
var win = app.windows.at(i);
if(!win.selectedTab.busy()){
app.close(win, {saving:"no"})
}
}
}
// function safariWindows(){
// windowIDs = []
// var app = Application("Safari")
// for(var i = 0; i < app.windows().length; i++){
// var win = app.windows.at(i)
// windowIDs.push(win.id())
// }
// return windowIDs
// }
function title(app, win){
return Application(app).windows.byId(win).name()
}
// function needWindows(app, count, path){
// windowIDs = []
// var app = Application(app)
// if(app.windows().length < count){
// needed = count - app.windows().length
// console.log(needed)
// for(var i = 0; i < needed; i++ ){
// app.open(path)
// }
// }
// delay(1)
// for(var i = 0; i < app.windows().length; i++){
// var win = app.windows.at(i)
// windowIDs.push(win.id())
// }
// return windowIDs
// }
function writeFile(pPathStr, pOutputStr) {
//--- CONVERT TO NS STRING ---
var nsStr = $.NSString.alloc.initWithUTF8String(pOutputStr)
//--- EXPAND TILDE AND CONVERT TO NS PATH ---
var nsPath = $(pPathStr).stringByStandardizingPath
//--- WRITE TO FILE ---
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + pPathStr)
}
return successBool
}
function writeJson(path, obj) {
try{
var str = JSON.stringify(obj, null, 2)
}catch(err){ return [false, "JSON error"]}
try{
writeFile(path, str)
}catch(err){ return [false, "file error"] }
return [true, obj]
}
function store(k, v) {
var path = workspacePropertiesFile()
var result = readJson(path)
var obj = {}
if(result[0]){
obj = result[1]
}
obj[k] = v
var result = writeJson(path, obj)
var success = result[0]
if(!success){
console.log("could not write JSON")
return result
}
return [true, v]
}
function workspacePropertiesFile(){
return workspaceHome() + "/" + "properties.json"
}
/**
@desc Reads objects from JSON file
@param {String} key The key to get values from
@returns {Array}
*/
function retrieve(k) {
var path = workspacePropertiesFile()
var result = readJson(path)
var success = result[0]
if(!success){
return result
}
var obj = result[1]
var v = obj[k]
if(v == undefined) return [false, "key error"]
return [true, v]
}
function retrieve(k) {
var path = workspacePropertiesFile()
var result = readJson(path)
var success = result[0]
if(!success){
console.log("retrieve", result[1])
return result
}
var obj = result[1]
var v = obj[k]
if(v == undefined){
console.log("retrieve key error")
return [false, "key error"]
}
return [true, v]
}
function readJson(path) {
var data = readFile(path)
if(!data[0]){ return [false, "file error"] }
try{
var obj = JSON.parse(data[1])
}catch(err){
return [false, "JSON error"]
}
return [true, obj]
}
function readFile(file) {
var app = Application.currentApplication()
app.includeStandardAdditions = true
// Convert the file to a string
var fileString = file.toString()
try{
var p = Path(fileString)
}catch(err){ return [false, err] }
try{
var str = app.read(p)
}catch(err){
return [false, err]
}
// Read the file and return its contents
return [true, str]
}
function toggleActiveWindowFullScreen(){
sys_events.keystroke('f', { using: ['control down','command down'] });
}
/**
*
* Get environment variable by name
*
*/
function env(name){
var env = $.NSProcessInfo.processInfo.environment // -[[NSProcessInfo processInfo] environment]
env = ObjC.unwrap(env)
for (var k in env) {
if(k == name){
return ObjC.unwrap(env[k])
}
}
return undefined
}
/**
*
* Print available environment variables
*
*/
function env_list(){
var env = $.NSProcessInfo.processInfo.environment // -[[NSProcessInfo processInfo] environment]
env = ObjC.unwrap(env)
for (var k in env) {
console.log('"' + k + '": ' + ObjC.unwrap(env[k]))
}
}
/**
@desc Get list of workspace-related windows from file. If there
are stored windows that do not exist, they will be removed.
@param {String} appName
@returns {Array} List of objects in the form {id:2445, }
*/
function existingWorkspaceWindows(appName) {
if(appName == undefined){
console.log("no app name given")
return []
}
// console.log(appName)
// appName = lowerCase(appName)
var result = retrieve(appName)
var success = result[0]
var wlist = result[1]
// console.log("window count", wlist.length)
if(!success){
return []
}
var changed = false
for (var i = 0; i < wlist.length; i++) {
var id = wlist[i]["id"]
// console.log("window exist", id, windowExistWithId(appName, id))
if(!windowExistWithId(appName, id)){
wlist.splice(i, 1)
changed = true
}
}
if(changed){
store(appName, wlist)
}
return wlist
}
/**
@desc Get list of workspace-related windows from file. If there
are stored windows that do not exist, they will be removed.
@param {String} appName
@returns {Array} List of objects in the form {id:2445, }
*/
function workspaceWindows(appName) {
if(appName == undefined){
console.log("no app name given")
return []
}
// console.log(appName)
// appName = lowerCase(appName)
var result = retrieve(appName)
var success = result[0]
var wlist = result[1]
// console.log("window count", wlist.length)
if(!success){
return []
}
var changed = false
for (var i = 0; i < wlist.length; i++) {
var id = wlist[i]["id"]
// console.log("window exist", id, windowExistWithId(appName, id))
if(!windowExistWithId(appName, id)){
wlist.splice(i, 1)
changed = true
}
}
if(changed){
store(appName, wlist)
}
return wlist
}
/**
@param {String} appName
@param {Integer} id
@returns {Boolean}
**/
function windowExistWithId(appName, id) {
var wlist = windowIDs(appName)
for (var i = 0; i < wlist.length; i++) {
var wID = wlist[i]
if(id == wID) return true
}
return false
}
/**
@desc Get list of id's of Safari windows.
@param {String} appName
@returns {Array} Array of integers
**/
function windowIDs(appName){
// console.log(appName)
var app = Application(appName)
// console.log(app)
var wlist = []
for(var i = 0; i < app.windows().length; i++){
var win = app.windows.at(i)
wlist.push(win.id())
}
return wlist.sort(function(a, b){return a-b})
}
/**
@desc Get window id by index from list of all windows.
@param {Integer} index may be -2, -1, 0, 1, 2, etc.
@return {Integer}
**/
function windowID(appName, index){
var app = Application(appName)
var wlist = windowIDs(appName)
if(index < 0){
index = wlist.length + index
}
return app.windows.byId(wlist[index]).id()
}
// cannot call safari.foo() here, because
// somehow this library cannot import library safari in here
function add(appName){
// var wlist = workspaceWindows2(appName)
if(appName == "Safari"){
console.log("sys.add", appName)
// safari.addWorkspaceWindow()
}
return false
}
function prompt(text, defaultAnswer) {
var t = Application("Terminal")
t.includeStandardAdditions = true
var options = { defaultAnswer: defaultAnswer || '' }
try {
return t.displayDialog(text, options).textReturned
} catch (e) {
return defaultAnswer
}
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Add Window To Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
<key>NSRequiredContext</key>
<dict>
<key>NSApplicationIdentifier</key>
<string>com.apple.Safari</string>
</dict>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace")
var name = workspace.chooseFromList("Add Window")
if(name){
var title = workspace.chooseFromSafariWindows()
console.log(title)
var id = workspace.safariWindowWithTitle(title)
console.log(id)
workspace.addWindowToWorkspace(id, name)
}
</string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>37B74330-193E-4E8D-B449-ED2F571F6AE5</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>7B06B951-BB15-4304-B518-A1341F0FFE23</string>
<key>UUID</key>
<string>FF274825-2F9A-47B9-9400-46CEA70220FA</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>conversionLabel</key>
<integer>0</integer>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceApplicationBundleID</key>
<string>com.apple.Safari</string>
<key>serviceApplicationPath</key>
<string>/Applications/Safari.app</string>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Close Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
<key>NSRequiredContext</key>
<dict>
<key>NSApplicationIdentifier</key>
<string>com.apple.Safari</string>
</dict>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace") var name = workspace.chooseFromList("Close Workspace") if(name){ workspace.closeWindows(name) } </string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>7F9F1DE1-A7A7-49ED-A176-8CDD7720140D</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>16DCD07D-E279-4864-8A3C-5DC99A710768</string>
<key>UUID</key>
<string>D470416C-8650-4D12-BAC5-BB0A833E5B38</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceApplicationBundleID</key>
<string>com.apple.Safari</string>
<key>serviceApplicationPath</key>
<string>/Applications/Safari.app</string>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>New Window in Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace") var name = workspace.chooseFromList("New Window") if(name){ workspace.addNewWindowTo(name) } </string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>190315AD-4027-4B5C-84D3-69AB00B3AFC9</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>CD7CCA8B-A359-4B72-AB5D-BE73FB396D47</string>
<key>UUID</key>
<string>28E27097-50F3-41CE-92CF-4CE61B499309</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>New Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
<key>NSRequiredContext</key>
<dict>
<key>NSApplicationIdentifier</key>
<string>com.apple.Safari</string>
</dict>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace") var app = Application.currentApplication() app.includeStandardAdditions = true var response = app.displayDialog("Enter Name for New Workspace", { defaultAnswer: "", withIcon: "note", buttons: ["Cancel", "Continue"], defaultButton: "Continue" }) var selectedWorkspaceName = response.textReturned var allWorkspaceNames = workspace.getNames() for (var i = 0; i &lt; allWorkspaceNames.length; i++) { if(allWorkspaceNames[i] == selectedWorkspaceName){ var response = app.displayDialog(" Workspace name already used. Please choose another", { defaultAnswer: "", withIcon: "note" }) } } var selectedWorkspaceProps = { Safari: [] } workspace.saveProperties(selectedWorkspaceName, selectedWorkspaceProps) workspace.addNewWindowTo(selectedWorkspaceName) // Result: {"buttonReturned":"Continue", "textReturned":"Jen"} // app.displayDialog("Hello, " + (response.textReturned) + ".")</string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>FBE6C993-52EE-41D0-BD21-930E380F6DDF</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>B523AC97-AB88-4C3B-9AD9-7A312D268481</string>
<key>UUID</key>
<string>209EE2EE-6708-4074-A81D-C22F65CAC830</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceApplicationBundleID</key>
<string>com.apple.Safari</string>
<key>serviceApplicationPath</key>
<string>/Applications/Safari.app</string>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Open Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
<key>NSRequiredContext</key>
<dict>
<key>NSApplicationIdentifier</key>
<string>com.apple.Safari</string>
</dict>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace") var name = workspace.chooseFromList("Open Workspace") if(name){ workspace.openWindows(name) } </string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>9200F188-26ED-423E-8D71-61A932B6BE4C</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>2F558129-08B8-481D-9E70-569BCD136E2F</string>
<key>UUID</key>
<string>E99A67F6-D636-437E-BDF8-E5DD1DD9A644</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceApplicationBundleID</key>
<string>com.apple.Safari</string>
<key>serviceApplicationPath</key>
<string>/Applications/Safari.app</string>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Save Workspace</string>
</dict>
<key>NSMessage</key>
<string>runWorkflowAsService</string>
<key>NSRequiredContext</key>
<dict>
<key>NSApplicationIdentifier</key>
<string>com.apple.Safari</string>
</dict>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AMApplicationBuild</key>
<string>419</string>
<key>AMApplicationVersion</key>
<string>2.6</string>
<key>AMDocumentVersion</key>
<string>2</string>
<key>actions</key>
<array>
<dict>
<key>action</key>
<dict>
<key>AMAccepts</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Optional</key>
<true/>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>AMActionVersion</key>
<string>1.0</string>
<key>AMApplication</key>
<array>
<string>Automator</string>
</array>
<key>AMParameterProperties</key>
<dict>
<key>source</key>
<dict/>
</dict>
<key>AMProvides</key>
<dict>
<key>Container</key>
<string>List</string>
<key>Types</key>
<array>
<string>com.apple.applescript.object</string>
</array>
</dict>
<key>ActionBundlePath</key>
<string>/System/Library/Automator/Run JavaScript.action</string>
<key>ActionName</key>
<string>Run JavaScript</string>
<key>ActionParameters</key>
<dict>
<key>source</key>
<string>var workspace = Library("workspace") var name = workspace.chooseFromList("Save Workspace") if(name){ workspace.saveWindows(name, workspace.readProperties(name)) } </string>
</dict>
<key>BundleIdentifier</key>
<string>com.apple.Automator.RunJavaScript</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CanShowSelectedItemsWhenRun</key>
<false/>
<key>CanShowWhenRun</key>
<true/>
<key>Category</key>
<array>
<string>AMCategoryUtilities</string>
</array>
<key>Class Name</key>
<string>RunJavaScriptAction</string>
<key>InputUUID</key>
<string>DD014771-EE7F-4EDD-9B50-AF9B03DA109A</string>
<key>Keywords</key>
<array>
<string>Run</string>
<string>JavaScript</string>
</array>
<key>OutputUUID</key>
<string>B727F99B-F58C-4CD5-80D5-DB5FAEA23AC8</string>
<key>UUID</key>
<string>6429699E-98F2-402B-ABE3-B57AFA0D5485</string>
<key>UnlocalizedApplications</key>
<array>
<string>Automator</string>
</array>
<key>arguments</key>
<dict>
<key>0</key>
<dict>
<key>default value</key>
<string>function run(input, parameters) {
// Your script goes here
return input;
}</string>
<key>name</key>
<string>source</string>
<key>required</key>
<string>0</string>
<key>type</key>
<string>0</string>
<key>uuid</key>
<string>0</string>
</dict>
</dict>
<key>isViewVisible</key>
<true/>
<key>location</key>
<string>309.000000:316.000000</string>
<key>nibPath</key>
<string>/System/Library/Automator/Run JavaScript.action/Contents/Resources/Base.lproj/main.nib</string>
</dict>
<key>isViewVisible</key>
<true/>
</dict>
</array>
<key>connectors</key>
<dict/>
<key>workflowMetaData</key>
<dict>
<key>serviceApplicationBundleID</key>
<string>com.apple.Safari</string>
<key>serviceApplicationPath</key>
<string>/Applications/Safari.app</string>
<key>serviceInputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceOutputTypeIdentifier</key>
<string>com.apple.Automator.nothing</string>
<key>serviceProcessesInput</key>
<integer>0</integer>
<key>workflowTypeIdentifier</key>
<string>com.apple.Automator.servicesMenu</string>
</dict>
</dict>
</plist>

289
workspace.js Normal file
View File

@ -0,0 +1,289 @@
var systemEvents = Application("System Events")
var os = Library("os")
var workspacesDir = os.env("HOME") + "/.safari-workspaces"
function getNames() {
var items = systemEvents.aliases.byName(workspacesDir).diskItems;
var selectedItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.class() != "folder" && item.visible()) {
selectedItems.push(item.name().substring(0, item.name().length - 5));
}
}
return selectedItems;
}
function chooseFromList(title) {
if(!title){
title = "Choose Workspace"
}
var app = Application.currentApplication()
app.includeStandardAdditions = true
app.activate()
var choices = getNames()
var choice = app.chooseFromList(choices, {
withPrompt: title,
defaultItems: choices[0],
buttons: ["Cancel", "OK"],
defaultButton: "OK"
})
// if(!choice){
// choice = ""
// }
return choice
}
function getSafariWindowTitles() {
var app = Application('Safari')
var titles = []
var windows = app.windows()
for (var k = 0; k < windows.length; k++) {
var url = app.windows.at(k).currentTab.url()
var name = app.windows.at(k).currentTab.name()
var id = app.windows.at(k).id()
titles.push(name)
}
return titles
}
function safariWindowWithTitle(title) {
var app = Application('Safari')
var windows = app.windows()
for (var k = 0; k < windows.length; k++) {
var name = app.windows.at(k).currentTab.name()
if(name == title){
var id = app.windows.at(k).id()
return id
}
}
return -1
}
function chooseFromSafariWindows() {
var app = Application.currentApplication()
app.includeStandardAdditions = true
app.activate()
var choices = getSafariWindowTitles()
var choice = app.chooseFromList(choices, {
withPrompt: "Choose Window:",
defaultItems: choices[0]
})
return choice
}
function saveProperties(workspaceName, workspaceProps) {
var path = workspacesDir + "/" + workspaceName + ".json"
var result = os.writeJson(path, workspaceProps)
var success = result[0]
return success
}
function readProperties(workspaceName) {
var result = os.readJson(workspacesDir + "/" + workspaceName + ".json")
if(result[0]){
return result[1]
}
return {error: "workspace not found"}
}
function addTab(id, url){
var app = Application("Safari")
var tab = app.Tab()
tab.url = url
var win = app.windows.byId(id)
win.tabs.push(tab)
}
function allWindows(){
var app = Application("Safari")
var windows = []
for(var i = 0; i < app.windows().length; i++){
windows.push(app.windows.at(i).id())
}
return windows.sort(function(a, b){return a-b})
}
function newWindow(url){
var app = Application("Safari")
app.activate()
if(url){
app.Document({url: url}).make()
}else{
app.Document().make()
}
var windows = allWindows()
return windows[windows.length - 1]
}
function addNewWindowTo(workspaceName) {
var workspaceProps = readProperties(workspaceName)
var winID = newWindow()
var workspaceWindow = {id: winID, tabs: []}
workspaceProps["Safari"].push(workspaceWindow)
saveProperties(workspaceName, workspaceProps)
}
function shouldIgnoreUrl(url) {
var urls = [
"https://gl.intermodi.cc",
"https://news.ycombinator.com",
"https://git.iris-cloud.de",
"https://web.threema.ch",
"https://kdw.intermodi.cc",
"http://euangoddard.github.io/clipboard2markdown/",
"safari-resource:/ErrorPage.html"
]
for (var i = 0; i < urls.length; i++) {
if(url.startsWith(urls[i])){
return true
}
}
return false
}
function openWindows(workspaceName) {
var workspaceProps = readProperties(workspaceName)
var app = Application("Safari")
for (var i = 0; i < workspaceProps["Safari"].length; i++) {
var workspaceWindow = workspaceProps["Safari"][i]
var windowExists = false
for(var j = 0; j < app.windows().length; j++){
var openWindow = app.windows.at(j)
if(openWindow.id() == workspaceWindow.id){
windowExists = true
}
}
if(!windowExists){
var firstTab = workspaceWindow.tabs[0]
var newWindowID = newWindow(firstTab)
// console.log("new window created", newWindowID)
workspaceWindow.id = newWindowID
for (var k = 1; k < workspaceWindow.tabs.length; k++) {
// console.log(workspaceWindow.tabs[k])
var url = workspaceWindow.tabs[k]
if(!shouldIgnoreUrl(url)){
addTab(newWindowID, workspaceWindow.tabs[k])
}
}
}else{
console.log("window exists", workspaceWindow.id)
}
saveProperties(workspaceName, workspaceProps)
}
}
function saveWindows(workspaceName, workspaceProps) {
var app = Application("Safari")
for(var i = 0; i < app.windows().length; i++){
var openWindow = app.windows.at(i)
// console.log("Safari window", openWindow.id())
for (var j = 0; j < workspaceProps["Safari"].length; j++) {
var workspaceWindow = workspaceProps["Safari"][j]
if(openWindow.id() == workspaceWindow.id){
workspaceWindow.tabs = []
for (var k = 0; k < app.windows.at(i).tabs.length; k++) {
var url = openWindow.tabs.at(k).url()
if(url){
if(!shouldIgnoreUrl(url)){
workspaceWindow.tabs.push(url)
}
}
}
}
}
}
log(workspaceProps)
saveProperties(workspaceName, workspaceProps)
}
function log(obj) {
console.log(JSON.stringify(obj, null, 2))
}
function addWindowToWorkspace(id, workspaceName) {
var app = Application("Safari")
var openWindow = app.windows.byId(id)
var workspaceProps = readProperties(workspaceName)
var workspaceWindow = {id: id, tabs: []}
for (var k = 0; k < openWindow.tabs.length; k++) {
var url = openWindow.tabs.at(k).url()
if(url){
if(!shouldIgnoreUrl(url)){
workspaceWindow.tabs.push(url)
}
}
}
workspaceProps["Safari"].push(workspaceWindow)
saveWindows(workspaceName, workspaceProps)
}
// todo: choose from list for window to remove from workspace
function closeWindows(workspaceName) {
var app = Application("Safari")
var workspaceProps = readProperties(workspaceName)
saveWindows(workspaceName, workspaceProps)
var windowsToRemove = []
for (var i = 0; i < workspaceProps["Safari"].length; i++) {
var workspaceWindow = workspaceProps["Safari"][i]
try{
app.close(app.windows.byId(workspaceWindow.id))
}catch(err){
// fenster die vorher manuell geschlossen wurden
// werden aus der liste an fenstern entfernt
// windowsToRemove.push(workspaceProps["Safari"][i].id)
}
}
// for (var i = 0; i < workspaceProps["Safari"].length; i++) {
// var workspaceWindow = workspaceProps["Safari"][i]
// for (var j = 0; j < windowsToRemove.length; j++) {
// if(workspaceWindow.id == windowsToRemove[j]){
// try{
// workspaceProps["Safari"].splice([i], 1)
// }catch(err){
// }
// }
// }
// }
}