Skip to content

Commit 7326d9d

Browse files
authored
Merge pull request #27 from amarcu5/develop
v0.2.3
2 parents 6188d0e + 0eb1ffd commit 7326d9d

File tree

11 files changed

+566
-201
lines changed

11 files changed

+566
-201
lines changed

README.md

+126-10
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,33 @@ Adds Picture in Picture functionality to Safari for YouTube, Netflix, Amazon Vid
33

44
<img src="/promo/Promo-shot.png" alt="Screenshot of PiPer in action" width="512" />
55

6-
## Installation
6+
## Features
7+
* Adds a dedicated Picture in Picture button to the video player of [supported sites](#supported-sites)
8+
* Button integrates seamlessly with the player including hover effects and tooltips
9+
* Supports closed captions in Picture and Picture mode
10+
* Free and open source
711

12+
## Installation
813
Get the latest release from the [Safari Extension Gallery](https://safari-extensions.apple.com/details/?id=com.amarcus.safari.piper-BQ6Q24MF9X)
914

10-
<sub>...or live life on the edge with the latest [developer build](https://rawgit.com/amarcu5/PiPer/develop/out/PiPer.safariextz) (IMPORTANT: these builds do not update automatically!)</sub>
15+
<sub>...or live life on the edge with the latest [development build](https://rawgit.com/amarcu5/PiPer/develop/out/PiPer.safariextz) (IMPORTANT: these builds do not update automatically!)</sub>
1116

1217
## Supported sites
13-
* [Amazon video](http://www.amazon.com/PrimeVideo)
18+
* [Amazon Video](http://www.amazon.com/PrimeVideo)
1419
* [CollegeHumor](http://www.collegehumor.com)
1520
* [CuriosityStream](http://www.curiositystream.com)
21+
* [Eurosport player](http://www.eurosportplayer.com)
22+
* [Giant Bomb](http://www.giantbomb.com)
1623
* [Hulu](http://www.hulu.com)
1724
* [LittleThings](http://www.littlethings.com)
1825
* [Mashable](http://www.mashable.com)
1926
* [Metacafe](http://www.metacafe.com)
2027
* [Mixer](http://mixer.com)
21-
* [NCAA](http://www.ncaa.com)
2228
* [Netflix](http://www.netflix.com)
29+
* [OCS](http://www.ocs.fr)
2330
* [Openload](http://www.openload.co)
2431
* [Plex](http://www.plex.tv)
32+
* [Streamable](http://streamable.com)
2533
* [The Onion](http://www.theonion.com)
2634
* [Twitch](http://www.twitch.tv)
2735
* [Udemy](http://www.udemy.com)
@@ -31,12 +39,120 @@ Get the latest release from the [Safari Extension Gallery](https://safari-extens
3139
* [VRV](http://www.vrv.co)
3240
* [YouTube](http://www.youtube.com)
3341

34-
## Acknowledgements
35-
* [Pied PíPer](https://github.com/JoeKuhns/PiedPiPer.safariextension) for the original inspiration and the Netflix icon
36-
* [Google](https://github.com/google/material-design-icons) for the Picture in Picture icon
42+
## Changelog
43+
You can find information about releases [here](https://github.com/amarcu5/PiPer/releases)
44+
45+
## Development
46+
47+
### Building
48+
49+
#### Prerequisites
50+
* Mac running macOS 10.12 Sierra or later
3751

38-
## Build tools
52+
#### Build tools
53+
For convenience the following Node.js tools have been packaged with [nexe](https://github.com/nexe/nexe) and included in this repository:
54+
* [csso](https://github.com/css/csso) (3.1.1) for compressing CSS
3955
* [svgo](https://github.com/svg/svgo) (0.7.2) for compressing SVG images
4056
* [xarjs](https://github.com/robertknight/xar-js) (0.2.0) for packaging Safari extension
41-
* [ccjs](https://github.com/google/closure-compiler-js) (1.6.1) for compiling JavaScript
42-
* [plistbuddy](https://github.com/amarcu5/PiPer/tree/master/build-tools/) for automated build numbering - reimplementation of utility from [Apple's Command Line Tools](https://developer.apple.com/download/)
57+
* [google-closure-compiler-js](https://github.com/google/closure-compiler-js) (20170806.0.0) for compiling JavaScript
58+
59+
However it is recommended to install the latest versions with [Node.js](https://nodejs.org):
60+
```Shell
61+
npm install -g csso-cli
62+
npm install -g svgo
63+
npm install -g xar-js
64+
npm install -g google-closure-compiler-js
65+
```
66+
67+
Additionally a reimplementation of the utility PlistBuddy used for automated build numbering is [provided](https://github.com/amarcu5/PiPer/tree/master/build-tools/) but it is advisable to download the original as part of [Xcode](https://itunes.apple.com/gb/app/xcode/id497799835?mt=12) or from [Apple's Command Line Tools](https://developer.apple.com/download/)
68+
69+
#### Steps
70+
1. Clone the repository
71+
2. Run `make.sh`
72+
1. By default this builds the unoptimized and unpackaged development version into the `./out/` directory that can then be installed using Safari's Extension Builder
73+
2. Alternatively run `./make.sh -p release` to build the optimized and packaged release version (note that packaging requires a private key)
74+
75+
### Supporting a new site
76+
If we wanted to support `example.com` with the source:
77+
```HTML
78+
<div class="video-container">
79+
<video src="blob:http://example.com/342b3a13-c892-54ec-84f6-281579de03ab"></video>
80+
<div class="video-captions">
81+
Example caption
82+
</div>
83+
<div class="video-controls">
84+
<button class="control button-play">Play</button>
85+
<button class="control button-fullscreen">Fullscreen</button>
86+
</div>
87+
</div>
88+
```
89+
We would start by adding a new entry in the `resources` object in `main.js`:
90+
```JavaScript
91+
const resources = {
92+
...
93+
'example' : {
94+
buttonParent: function() {
95+
// Returns the element that will contain the button
96+
return document.querySelector('.video-controls');
97+
},
98+
videoElement: function() {
99+
// Returns the video element
100+
return document.querySelector('.video-container video');
101+
},
102+
103+
// Optional
104+
captionElement: function() {
105+
// Returns the element that contains the video captions
106+
return document.querySelector('.video-captions');
107+
},
108+
},
109+
};
110+
```
111+
We also need to update the extension permissions to support the new site by editing `./src/Info.plist`:
112+
```XML
113+
<?xml version="1.0" encoding="UTF-8"?>
114+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://apple.com/DTDs/PropertyList-1.0.dtd">
115+
<plist version="1.0">
116+
<dict>
117+
<key>Permissions</key>
118+
<dict>
119+
<key>Website Access</key>
120+
<dict>
121+
...
122+
<key>Allowed Domains</key>
123+
<array>
124+
...
125+
<string>example.com</string>
126+
<string>*.example.com</string>
127+
</array>
128+
</dict>
129+
</dict>
130+
</dict>
131+
</plist>
132+
```
133+
We might want to style the button so that it integrates with the page better:
134+
```JavaScript
135+
const resources = {
136+
...
137+
'example' : {
138+
...
139+
// Assign a CSS class
140+
buttonClassName: 'control',
141+
// Scale the button
142+
buttonScale: 0.5,
143+
// Apply custom CSS styles
144+
buttonStyle: /** CSS */ (`
145+
/* Declaring CSS this way ensures it gets optimized when the extension is built */
146+
cursor: pointer;
147+
opacity: 0.5;
148+
`),
149+
// Apply a custom CSS hover style
150+
buttonHoverStyle: /** CSS */ (`opacity: 1 !important`),
151+
},
152+
};
153+
```
154+
For more examples, please see the [source](https://github.com/amarcu5/PiPer/tree/master/src/scripts)
155+
156+
## Acknowledgements
157+
* [Pied PíPer](https://github.com/JoeKuhns/PiedPiPer.safariextension) for the original inspiration and the Netflix icon
158+
* [Google](https://github.com/google/material-design-icons) for the Picture in Picture icon

build-tools/ccjs

-6.12 MB
Binary file not shown.

build-tools/csso

5.92 MB
Binary file not shown.
6.39 MB
Binary file not shown.

make.sh

+121-37
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,88 @@
11
#!/bin/bash
2-
3-
#
4-
# Settings
52
#
3+
# Make the PiPer Safari extension
64

75
EXTENSION_NAME="PiPer"
86

9-
# Paths
10-
CCJS_PATH="./build-tools/ccjs" # "ccjs"
11-
XARJS_PATH="./build-tools/xarjs" # "xarjs"
12-
SVGO_PATH="./build-tools/svgo" # "svgo"
13-
PLISTBUDDY_PATH="./build-tools/plistbuddy" # "/usr/libexec/PlistBuddy"
7+
# Build tool paths; fallback to local build tools
8+
CSSO_PATH=$(type "csso" >/dev/null 2>&1 && echo "csso" || echo "./build-tools/csso")
9+
CCJS_PATH=$(type "google-closure-compiler-js" >/dev/null 2>&1 && echo "google-closure-compiler-js" || echo "./build-tools/google-closure-compiler-js")
10+
XARJS_PATH=$(type "xarjs" >/dev/null 2>&1 && echo "xarjs" || echo "./build-tools/xarjs")
11+
SVGO_PATH=$(type "svgo" >/dev/null 2>&1 && echo "svgo" || echo "./build-tools/svgo")
12+
PLISTBUDDY_PATH=$(type "/usr/libexec/PlistBuddy" >/dev/null 2>&1 && echo "/usr/libexec/PlistBuddy" || echo "./build-tools/plistbuddy")
1413

15-
# Certifcates
14+
# Certifcate paths
1615
LEAF_CERT_PATH="../certs/cert.pem"
1716
INTERMEDIATE_CERT_PATH="../certs/apple-intermediate.pem"
1817
ROOT_CERT_PATH="../certs/apple-root.pem"
1918
PRIVATE_KEY_PATH="../certs/privatekey.pem"
2019

2120

21+
# Display help then exit
22+
show_help() {
23+
cat << EOF
24+
Usage: make.sh [options]
25+
26+
Options:
27+
-h -? --help Show this screen
28+
-p --profile <release|debug> Set settings according to profile [default: debug]
29+
-c --compress-css Compress CSS
30+
-j --compress-js Compress JavaScript
31+
-s --compress-svg Compress SVG
32+
-e --package-extension Package Safari extension (requires private key)
33+
-v --no-version-increment Disable automatic version incrementing
34+
EOF
35+
exit 0
36+
}
37+
38+
arguments=("$@")
39+
40+
# First pass processing arguments
41+
while :; do
42+
case $1 in
43+
-h|-\?|--help) show_help ;;
44+
-p|--profile) [[ "$2" ]] && profile=$2 ;;
45+
--profile=?*) profile=${1#*=} ;;
46+
-?*) ;;
47+
*) break
48+
esac
49+
shift
50+
done
51+
52+
# Set default settings as per profile
53+
case $profile in
54+
release)
55+
compress_svg=1
56+
compress_css=1
57+
compress_js=1
58+
package_ext=1
59+
;;
60+
*)
61+
compress_svg=0
62+
compress_css=0
63+
compress_js=0
64+
package_ext=0
65+
esac
66+
update_version=1
67+
68+
set -- "${arguments[@]}"
69+
70+
# Second pass processing arguments
71+
while :; do
72+
case $1 in
73+
-c|--compress-css) compress_css=1 ;;
74+
-j|--compress-js) compress_js=1 ;;
75+
-s|--compress-svg) compress_svg=1 ;;
76+
-e|--package-extension) package_ext=1 ;;
77+
-v|--no-version-increment) update_version=0 ;;
78+
-p|--profile) shift ;;
79+
-?*) ;;
80+
*) break
81+
esac
82+
shift
83+
done
84+
85+
2286
#
2387
# Build script
2488
#
@@ -37,41 +101,61 @@ mkdir -p "out/${EXTENSION_NAME}.safariextension"
37101
cp -r src/* "out/${EXTENSION_NAME}.safariextension/"
38102

39103
# Compress all supported images with SVGO
40-
${SVGO_PATH} -q -f "out/${EXTENSION_NAME}.safariextension/images"
104+
if [[ "$compress_svg" -eq 1 ]]; then
105+
${SVGO_PATH} -q -f "out/${EXTENSION_NAME}.safariextension/images"
106+
fi
107+
108+
# Compress all inline CSS with CSSO
109+
if [[ "$compress_css" -eq 1 ]]; then
110+
function minify_css() {
111+
echo "$@" | sed -e 's/\\"/"/g' -e 's/\\\$/$/g' | ${CSSO_PATH} --declaration-list
112+
}
113+
export -f minify_css
114+
export CSSO_PATH
115+
for path in "out/${EXTENSION_NAME}.safariextension/scripts"/*.js; do
116+
source=$(cat "${path}")
117+
echo "echo \"$(sed -e 's/\\/\\\\/g' -e 's/\$/\\$/g' -e 's/\`/\\`/g' -e 's/\"/\\\"/g' -e 's/\\n/\\\\n/g' <<< "$source" \
118+
| perl -0pe 's/\/\*\*\s+CSS\s+\*\/\s*\(\s*\\`(.*?)\\`\s*\)/\\`\$(minify_css '\''$1'\'')\\`/gms')\"" \
119+
| sh > "${path}"
120+
done
121+
fi
41122

42123
# Use closure compiler to compress javascript
43-
for path in "out/${EXTENSION_NAME}.safariextension/scripts"/*.js; do
44-
[ $(basename $path) == "externs.js" ] && continue
45-
path=${path%.*}
46-
${CCJS_PATH} \
47-
--compilationLevel ADVANCED \
48-
--warningLevel VERBOSE \
49-
--newTypeInf \
50-
--useTypesForOptimization \
51-
--externs "out/${EXTENSION_NAME}.safariextension/scripts/externs.js" \
52-
"${path}.js" > "${path}.min.js"
53-
mv "${path}.min.js" "${path}.js"
54-
done
124+
if [[ "$compress_js" -eq 1 ]]; then
125+
for path in "out/${EXTENSION_NAME}.safariextension/scripts"/*.js; do
126+
[[ $(basename $path) == "externs.js" ]] && continue
127+
path=${path%.*}
128+
${CCJS_PATH} \
129+
--compilationLevel ADVANCED \
130+
--warningLevel VERBOSE \
131+
--newTypeInf \
132+
--useTypesForOptimization \
133+
--externs "out/${EXTENSION_NAME}.safariextension/scripts/externs.js" \
134+
"${path}.js" > "${path}.min.js"
135+
mv "${path}.min.js" "${path}.js"
136+
done
137+
fi
55138
rm "out/${EXTENSION_NAME}.safariextension/scripts/externs.js"
56139

57140
# Update version info from git
58-
git=$(sh /etc/profile; which git)
59-
number_of_commits=$(($("$git" rev-list HEAD --count) + 1))
60-
git_release_version=$("$git" describe --tags --always --abbrev=0)
61-
git_release_version=${git_release_version%%-*};
62-
git_release_version=${git_release_version#*v};
63-
info_plist="out/${EXTENSION_NAME}.safariextension/Info.plist"
64-
update_plist="update.plist"
65-
${PLISTBUDDY_PATH} -c "Set :CFBundleVersion $number_of_commits" "$info_plist"
66-
${PLISTBUDDY_PATH} -c "Set :CFBundleShortVersionString ${git_release_version}" "$info_plist"
67-
${PLISTBUDDY_PATH} -c "Set \":Extension Updates:0:CFBundleVersion\" $number_of_commits" "$update_plist"
68-
${PLISTBUDDY_PATH} -c "Set \":Extension Updates:0:CFBundleShortVersionString\" ${git_release_version#*v}" "$update_plist"
141+
if [[ "$update_version" -eq 1 ]]; then
142+
git=$(sh /etc/profile; which git)
143+
number_of_commits=$(($("$git" rev-list HEAD --count) + 1))
144+
git_release_version=$("$git" describe --tags --always --abbrev=0)
145+
git_release_version=${git_release_version%%-*};
146+
git_release_version=${git_release_version#*v};
147+
info_plist="out/${EXTENSION_NAME}.safariextension/Info.plist"
148+
update_plist="update.plist"
149+
${PLISTBUDDY_PATH} -c "Set :CFBundleVersion $number_of_commits" "$info_plist"
150+
${PLISTBUDDY_PATH} -c "Set :CFBundleShortVersionString ${git_release_version}" "$info_plist"
151+
${PLISTBUDDY_PATH} -c "Set \":Extension Updates:0:CFBundleVersion\" $number_of_commits" "$update_plist"
152+
${PLISTBUDDY_PATH} -c "Set \":Extension Updates:0:CFBundleShortVersionString\" ${git_release_version#*v}" "$update_plist"
153+
fi
69154

70155
# Package safari extension
71-
cd out || exit
72-
if [ -f "${PRIVATE_KEY_PATH}" ]
73-
then
74-
[[ ${XARJS_PATH} != /* ]] && ! command -v "${XARJS_PATH}" >/dev/null 2>&1 && XARJS_PATH="../${XARJS_PATH}"
156+
cd out || exit
157+
if [[ "$package_ext" -eq 1 ]] && [[ -f "${PRIVATE_KEY_PATH}" ]]; then
158+
[[ ${XARJS_PATH} != /* ]] && ! type "${XARJS_PATH}" >/dev/null 2>&1 && XARJS_PATH="../${XARJS_PATH}"
75159
${XARJS_PATH} create "${EXTENSION_NAME}.safariextz" --cert "${LEAF_CERT_PATH}" --cert "${INTERMEDIATE_CERT_PATH}" --cert "${ROOT_CERT_PATH}" --private-key "${PRIVATE_KEY_PATH}" "${EXTENSION_NAME}.safariextension"
76160
rm -rf "${EXTENSION_NAME}.safariextension"
77161
fi

out/PiPer.safariextz

329 Bytes
Binary file not shown.

promo/Promo-shot.png

25.7 KB
Loading

src/Info.plist

+8-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
<string>*.collegehumor.com</string>
5353
<string>curiositystream.com</string>
5454
<string>*.curiositystream.com</string>
55+
<string>eurosportplayer.com</string>
56+
<string>*.eurosportplayer.com</string>
57+
<string>giantbomb.com</string>
58+
<string>*.giantbomb.com</string>
5559
<string>hulu.com</string>
5660
<string>*.hulu.com</string>
5761
<string>littlethings.com</string>
@@ -62,16 +66,18 @@
6266
<string>*.metacafe.com</string>
6367
<string>mixer.com</string>
6468
<string>*.mixer.com</string>
65-
<string>ncaa.com</string>
66-
<string>*.ncaa.com</string>
6769
<string>netflix.com</string>
6870
<string>*.netflix.com</string>
71+
<string>ocs.fr</string>
72+
<string>*.ocs.fr</string>
6973
<string>openload.co</string>
7074
<string>*.openload.co</string>
7175
<string>plex.tv</string>
7276
<string>*.plex.tv</string>
7377
<string>primevideo.com</string>
7478
<string>*.primevideo.com</string>
79+
<string>streamable.com</string>
80+
<string>*.streamable.com</string>
7581
<string>theonion.com</string>
7682
<string>*.theonion.com</string>
7783
<string>twitch.tv</string>

0 commit comments

Comments
 (0)