Safari Extension CSS Injection not loading - xcode

I built a Safari Extension in XCode from scratch. The main goal was to hide the video recommendations on YouTube when watching something - I figured I could do that using some css properties.
For testing purposes, I included some more style modifications.
/* Testing */
body {
background: red !important;
color: blue !important;
}
/* Hide column with video recommendations */
#secondary {
display: none !important;
}
For some reason these css properties, which I saved in nostyle.css, do not affect the site.
I followed the Apple Guide on injecting CSS Style Sheets as closely as I could, mainly by editing the Info.plist file:
I added the css file as a reference in NSExtension -> SFSafariStyleSheet -> Array -> Dictionary with Key Style Sheet (notice the space) and value nostyle.css (a file in the same directory as "script.js" that came together with the project default setup)
I added *.youtube.com to the list of allowed domains (among other URLs for testing purposes)
I got the script.js file to output messages in my console, although at a somewhat inconsistent rate.
I have not touched any other files (except I added some Icons to Assets.xcassets). The following shows the full content of my Info.plist file inside the Extension folder. It also contains a Toolbar Item (SFSafariToolbarItem) that appears in the menu bar in Safari but doesn't do anything on click (as intended).
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>DistractionFreeYouTube Extension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSExtension</key>
<dict>
<key>SFSafariStyleSheet</key>
<array>
<dict>
<key>Style Sheet</key>
<string>nostyle.css</string>
</dict>
</array>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.Safari.extension</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).SafariExtensionHandler</string>
<key>SFSafariContentScript</key>
<array>
<dict>
<key>Script</key>
<string>script.js</string>
</dict>
</array>
<key>SFSafariToolbarItem</key>
<dict>
<key>Action</key>
<string>Command</string>
<key>Identifier</key>
<string>Button</string>
<key>Image</key>
<string>ToolbarItemIcon.pdf</string>
<key>Label</key>
<string>Distraction Free</string>
</dict>
<key>SFSafariWebsiteAccess</key>
<dict>
<key>Allowed Domains</key>
<array>
<string>*.youtube.com</string>
</array>
<key>Level</key>
<string>Some</string>
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 (my name). All rights reserved.</string>
<key>NSHumanReadableDescription</key>
<string>This extension hides the column of recommended videos when watching YouTube videos.</string>
</dict>
</plist>
Here's a screenshot of my workspace.

check the manifest.json file in your app extension, make sure the key "content_scripts" has the css file you need:
"content_scripts": [{
"css": ["nostyle.css"],
"js": [ "script.js" ],
"matches": [ "*://*.youtube.com/*" ],
}],
And this is not mentioned in Apple documents but MDN WebExtensions Doc

Related

Xcode template doesn't pick the variable from popup

I'm writing an XCode template. Everything works perfectly fine if I use text value for the variable:
<dict>
<key>Identifier</key>
<string>appName</string>
<key>Required</key>
<string>true</string>
<key>Name</key>
<string>App name</string>
<key>Description</key>
<string>App name desc</string>
<key>Type</key>
<string>text</string>
<key>NotPersisted</key>
<string>true</string>
</dict>
But it doesn't, if I use popup:
<dict>
<key>Identifier</key>
<string>appName</string>
<key>Required</key>
<string>true</string>
<key>Name</key>
<string>App name</string>
<key>Description</key>
<string>App name desc</string>
<key>Type</key>
<string>popup</string>
<key>NotPersisted</key>
<string>true</string>
<key>Values</key>
<array>
<string>AppX</string>
<string>AppY</string>
</array>
</dict>
I'm accessing the variable like that:
class ___VARIABLE_appName:identifier___TestCase {}
Tried with:
___VARIABLE_appName:identifier___
___VARIABLE_appName___
___VARIABLE_appName:value___
and still nothing. I can of course just use text, but popup would be really better.
The solution for me was to create 2 folders (AppX and AppY) and store the duplicated templates inside them. The only thing that differs between these 2 files - is VARIABLE_appName - but by storing templates in different folders I remove the necessity to have it as a variable. So I hardcoded the value instead.
Instead of just Template1.swift I now have:
Folder AppX
-Template1.swift
Folder AppY
-Template2.swift

LaunchAgent cannot access macOS "protected" folders

I have a shell script which does this:
#!/bin/bash
ls -la "$HOME/Pictures/Photos Library.photoslibrary"
When I run this script in the shell it works fine. If I define a LaunchAgent (under $HOME/Library/LaunchAgents) which executes this script, I get the following error message:
ls: Photos Library.photoslibrary: Operation not permitted
My real script is invoking HashBackup (hb) which results in the same kind of error on all those "protected" folders (pictures, address book, etc...). But I was able to reproduce with a simple ls.
What am I supposed to do to fix this?
This is on macOS 10.14.6.
Thanks
Thanks to Gordon comment, I was able to follow the steps and fix my issue. The steps that actually worked for me are these ones.
For the sake of a more complete solution, here is a small CMake based solution:
main.cpp
#include <iostream>
int main()
{
std::cout << "Wrapper app which is authorized for full disk access so that the shell script can run with the same permission" << std::endl;
return 0;
}
backup_argon.sh
#!/bin/bash
# this is just a test... it should invoke hb instead
ls -la "$HOME/Pictures/Photos Library.photoslibrary"
Info.plist.in
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>LSUIElement</key>
<true/>
</dict>
</plist>
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
set(VERSION 1.0.0)
project(HashBackupLaunchAgent VERSION "${VERSION}")
set(CMAKE_CXX_STANDARD 17)
set(MACOSX_BUNDLE_BUNDLE_NAME "HashBackupLaunchAgent")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.pongasoft.HashBackupLaunchAgent")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "2021 pongasoft")
add_executable(HashBackupLaunchAgent MACOSX_BUNDLE main.cpp backup_argon.sh)
set_target_properties(HashBackupLaunchAgent PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist.in")
set_source_files_properties(backup_argon.sh PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
Compiling this project will result in an application (HashBackupLaunchAgent.app) which I copied under /Applications.
I then gave Full Disk Access privilege to this app under System Preferences/Security & Privacy/ Privacy
I then have a LaunchAgent with the following definition:
<?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>Label</key>
<string>com.ypujante.hashbackup.argon.plist</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/bin:/usr/bin:/usr/local/bin</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/Applications/HashBackupLaunchAgent.app/Contents/MacOS/backup_argon.sh</string>
</array>
<key>StandardOutPath</key>
<string>/Users/ypujante/Library/Logs/HashBackup/argon.log</string>
<key>StandardErrorPath</key>
<string>/Users/ypujante/Library/Logs/HashBackup/argon.log</string>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>7</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</array>
</dict>
</plist>
Note how the launch agent definition invokes the script inside the app not the app itself. And it works: the script inherits the full disk access privilege given to the app.

Why isn't my document being recognized as a bundle in a minimally privileged environment?

I've got a OS X app that saves to a bundle. It works fine until I log out and then back in as a guest user and then it just shows up as a folder. The structure of the folder looks fine and has the correct extension, it's just not showing up as the custom UTI document.
I have changed the plist to say that the document is a bundle and changed it in the document types part of the target. Again, it is only not working when logging in as Guest User and so has been rejected from the App Store. Any ideas?
Here's the relevant section of "QTReview-Info.plist:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>movr</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>QTReviewIconRed</string>
<key>CFBundleTypeMIMETypes</key>
<array/>
<key>CFBundleTypeName</key>
<string>QTReview</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.protogylabs.qtreview</string>
</array>
<key>LSTypeIsPackage</key>
<integer>1</integer>
<key>NSDocumentClass</key>
<string>MyDocument</string>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
The structure of the bundle is:
bundleFilename.movr (folder)
--Quicktime movie
--documentDictData
--annotationFiles (folder)
----image01.jpg
----image02.jpg

How can I suppress warnings in SublimeLinter for mixed spaces/tabs in comments?

Here is a link to a screenshot of the warnings:
I would like to be able to use the "cmd+/" shortcut to quickly comment out sections of code. Whenever I do, I get a bunch of space/tab mixing errors. I am required to use tabs for coding standards, but it seems Sublime 3 forces spaces for the comments. I also enjoy the error checking for space/tab mixing through non-commented code, so I would like to leave that intact if possible.
Is there a way to modify Sublime's settings to change the commenting shorcuts functionality or is there a way to modify SublimeLinter-jshint's settings to ignore these warnings?
Thanks in advance.
The easiest way to do this is to remove the space from after the //. Open your Packages folder via Preferences -> Browse Packages... and create a folder called JavaScript. I assume you're on OS X, so the full path to the folder is ~/Library/Application Support/Sublime Text 3/Packages. Next, create a new file in Sublime with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>Comments</string>
<key>scope</key>
<string>source.js, source.json</string>
<key>settings</key>
<dict>
<key>shellVariables</key>
<array>
<dict>
<key>name</key>
<string>TM_COMMENT_START</string>
<key>value</key>
<string>//</string>
</dict>
<dict>
<key>name</key>
<string>TM_COMMENT_START_2</string>
<key>value</key>
<string>/*</string>
</dict>
<dict>
<key>name</key>
<string>TM_COMMENT_END_2</string>
<key>value</key>
<string>*/</string>
</dict>
</array>
</dict>
<key>uuid</key>
<string>A67A8BD9-A951-406F-9175-018DD4B52FD1</string>
</dict>
</plist>
and save it in the Packages/JavaScript folder as Comments.tmPreferences. You'll notice that the TM_COMMENT_START value is //, whereas in the original it's //. Restart Sublime, and now when you're editing JavaScript or JSON files and hit Command ⌘/ your code will be commented out without the addition of a space.

Problem registering file type through UTIs

I'm using AquaticPrime for license generation in my app, and as the developer guide suggests I'm attempting to register a custom file extension, such that users can simply click on the license and my application will open it and can then verify the license.
To do this, I've added an exported UTI declaration to my Info.plist as follows:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeDescription</key>
<string>MyApp License File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.mycompany.myapplicense</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myapplicense</string>
</array>
</dict>
</dict>
</array>
However, when I double-click on a file with that extension it doesn't open in MyApp, and nor does MyApp appear as one of the recommended apps to open the file type with. As well, when viewing the Info panel for the file, the filetype description as specified above doesn't appear.
Can anyone see anything wrong with my UTI declaration, or is there something else that I've missed?
Thanks
You also need a CFBundleDocumentTypes declaration.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>MyAppLicenseIcon</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>MyAppLicenseHandler</string>
<key>LSItemContentTypes</key>
<array>
<string>com.mycompany.myapplicense</string>
</array>
</dict>
</array>
To add to this, in my case I've had to also make sure that I was entering the proper format UTI as such:
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
my file being a simple .plist, it still conforms to xml. You need to make sure you know which UTI format you conform to.

Resources