├── version.txt ├── admin ├── .gitignore ├── dist │ ├── screenshot.png │ ├── web-update.sh │ ├── README.md │ ├── addchangelog.sh │ ├── update-version.sh │ ├── build.sh │ ├── publish.sh │ ├── addchangelog.py │ └── index.html ├── aws-credentials.template.sh ├── s3-bucket-permission-policy.json ├── s3-iam-user-policy.json ├── README.md └── dep ├── sparkle ├── Sparkle.framework │ ├── Versions │ │ ├── Current │ │ └── A │ │ │ ├── Resources │ │ │ ├── fr_CA.lproj │ │ │ ├── pt.lproj │ │ │ ├── Autoupdate.app │ │ │ │ └── Contents │ │ │ │ │ ├── PkgInfo │ │ │ │ │ ├── MacOS │ │ │ │ │ └── Autoupdate │ │ │ │ │ ├── Resources │ │ │ │ │ ├── AppIcon.icns │ │ │ │ │ ├── SUStatus.nib │ │ │ │ │ ├── ar.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── cs.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── da.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── de.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── el.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── en.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── es.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── fr.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── is.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── it.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── ja.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── ko.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── nb.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── nl.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── pl.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── ro.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── ru.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── sk.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── sl.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── sv.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── th.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── tr.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── uk.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── pt_BR.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── pt_PT.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ ├── zh_CN.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ └── zh_TW.lproj │ │ │ │ │ │ └── Sparkle.strings │ │ │ │ │ └── Info.plist │ │ │ ├── SUStatus.nib │ │ │ ├── ar.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── cs.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── da.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── de.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── el.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── en.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── es.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── fr.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── is.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── it.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── ja.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── ko.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── nb.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── nl.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── pl.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── ro.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── ru.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── sk.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── sl.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── sv.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── th.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── tr.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── uk.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── pt_BR.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── pt_PT.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── zh_CN.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── zh_TW.lproj │ │ │ │ ├── Sparkle.strings │ │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ ├── Info.plist │ │ │ └── SUModelTranslation.plist │ │ │ ├── Sparkle │ │ │ └── Headers │ │ │ ├── Sparkle.h │ │ │ ├── SUVersionDisplayProtocol.h │ │ │ ├── SUAppcast.h │ │ │ ├── SUVersionComparisonProtocol.h │ │ │ ├── SUStandardVersionComparator.h │ │ │ ├── SUAppcastItem.h │ │ │ └── SUUpdater.h │ ├── Headers │ ├── Sparkle │ └── Resources └── LICENSE ├── Messenger ├── MEmbeddedRes.h ├── icon.icns ├── FBMApplication.h ├── prefix.pch ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── icon-128.png │ │ └── Contents.json ├── AppDelegate.h ├── JSObjWrapper.h ├── main.m ├── FBMApplication.m ├── JSObjWrapper.m ├── jsapi.h ├── Info.plist ├── WebPreferences.h ├── JSNotifications.js.mm ├── JSNotification.js.mm ├── JSClass.hh ├── JSClass.mm ├── AppDelegate.mm └── MEmbeddedRes.m ├── xcode-config ├── messenger-debug.xcconfig ├── messenger-release.xcconfig ├── common-debug.xcconfig ├── common-release.xcconfig ├── messenger.xcconfig └── common.xcconfig ├── js-env-research ├── beautify.sh ├── 7qBmLkcUE_k.js ├── KzPBZimeKDr.js ├── DbVL0yMlRcI.js ├── y3PWxFZtgFE.js └── FoHrp55D04d.js ├── Messenger.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── .gitignore ├── README.md └── changelog.xml /version.txt: -------------------------------------------------------------------------------- 1 | 0.0.4 2 | -------------------------------------------------------------------------------- /admin/.gitignore: -------------------------------------------------------------------------------- 1 | /aws-credentials.sh 2 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Messenger/MEmbeddedRes.h: -------------------------------------------------------------------------------- 1 | extern NSString* kErrorPNGDataURL; -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | fr.lproj -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt.lproj: -------------------------------------------------------------------------------- 1 | pt_BR.lproj -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /xcode-config/messenger-debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "common-debug" 2 | #include "messenger" 3 | -------------------------------------------------------------------------------- /Messenger/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/Messenger/icon.icns -------------------------------------------------------------------------------- /admin/dist/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/admin/dist/screenshot.png -------------------------------------------------------------------------------- /xcode-config/messenger-release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "common-release" 2 | #include "messenger" 3 | 4 | ONLY_ACTIVE_ARCH = YES 5 | -------------------------------------------------------------------------------- /Messenger/FBMApplication.h: -------------------------------------------------------------------------------- 1 | @interface FBMApplication : NSApplication 2 | 3 | - (void)sendEvent:(NSEvent*)event; 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /Messenger/prefix.pch: -------------------------------------------------------------------------------- 1 | #ifndef Messenger_prefix_pch 2 | #define Messenger_prefix_pch 3 | 4 | #import 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /admin/aws-credentials.template.sh: -------------------------------------------------------------------------------- 1 | export AWS_ACCESS_KEY_ID=ABCDEF 2 | export AWS_SECRET_ACCESS_KEY=abcdef1234 3 | export AWS_DEFAULT_REGION=us-west-1 4 | -------------------------------------------------------------------------------- /js-env-research/beautify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | for f in *.js; do 4 | uglifyjs --beautify 'indent_level:2,beautify:true' -o $f $f 5 | done 6 | -------------------------------------------------------------------------------- /Messenger/Images.xcassets/AppIcon.appiconset/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/Messenger/Images.xcassets/AppIcon.appiconset/icon-128.png -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/SUStatus.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /admin/dist/web-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | source ../aws-credentials.sh 4 | aws s3 cp index.html s3://fbmacmessenger.rsms.me/index.html 5 | aws s3 cp screenshot.png s3://fbmacmessenger.rsms.me/screenshot.png 6 | -------------------------------------------------------------------------------- /Messenger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/todo/fb-mac-messenger/master/sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Messenger/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppDelegate : NSObject 4 | 5 | - (IBAction)checkForUpdates:(id)sender; 6 | - (void)setActiveConversationAtIndex:(NSString *)index; 7 | 8 | @end 9 | 10 | -------------------------------------------------------------------------------- /xcode-config/common-debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "common" 2 | 3 | ONLY_ACTIVE_ARCH = YES 4 | GCC_OPTIMIZATION_LEVEL = 0 5 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited) 6 | COPY_PHASE_STRIP = NO 7 | //GCC_DYNAMIC_NO_PIC = NO 8 | SWIFT_OPTIMIZATION_LEVEL = -Onone 9 | METAL_ENABLE_DEBUG_INFO = YES 10 | -------------------------------------------------------------------------------- /Messenger/JSObjWrapper.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface JSObjWrapper : NSObject 4 | @property (readonly, nonatomic) JSContextRef jsctx; 5 | @property (readonly, nonatomic) JSObjectRef jsobj; 6 | - (instancetype)initWithJSContext:(JSContextRef)ctx object:(JSObjectRef)obj; 7 | @end 8 | -------------------------------------------------------------------------------- /Messenger/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Messenger 4 | // 5 | // Created by Rasmus Andersson on 4/8/15. 6 | // Copyright (c) 2015 Rsms. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /xcode-config/common-release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "common" 2 | 3 | GCC_TREAT_WARNINGS_AS_ERRORS = YES 4 | GCC_PREPROCESSOR_DEFINITIONS = NDEBUG 5 | VALIDATE_PRODUCT = YES 6 | COPY_PHASE_STRIP = YES 7 | ENABLE_NS_ASSERTIONS = NO 8 | //GCC_DYNAMIC_NO_PIC = YES 9 | METAL_ENABLE_DEBUG_INFO = NO 10 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym 11 | -------------------------------------------------------------------------------- /admin/s3-bucket-permission-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2008-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "AllowPublicRead", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "*" 9 | }, 10 | "Action": "s3:GetObject", 11 | "Resource": "arn:aws:s3:::fbmacmessenger.rsms.me/*" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /admin/s3-iam-user-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Statement": [ 3 | { 4 | "Effect": "Allow", 5 | "Action": "s3:ListAllMyBuckets", 6 | "Resource": "arn:aws:s3:::*" 7 | }, 8 | { 9 | "Effect": "Allow", 10 | "Action": "s3:*", 11 | "Resource": [ 12 | "arn:aws:s3:::fbmacmessenger.rsms.me", 13 | "arn:aws:s3:::fbmacmessenger.rsms.me/*" 14 | ] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /Messenger/FBMApplication.m: -------------------------------------------------------------------------------- 1 | #import "FBMApplication.h" 2 | #import "AppDelegate.h" 3 | 4 | @implementation FBMApplication 5 | 6 | - (void)sendEvent:(NSEvent *)event { 7 | // Cmd-1 .. Cmd-9 8 | if (event.type == NSKeyDown && (event.modifierFlags & NSCommandKeyMask) && event.keyCode >= 18 && event.keyCode <= 28) { 9 | [((AppDelegate*)self.delegate) setActiveConversationAtIndex:event.characters]; 10 | return; 11 | } 12 | 13 | [super sendEvent:event]; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /admin/dist/README.md: -------------------------------------------------------------------------------- 1 | # Releasing versions 2 | 3 | The `release-*` scripts are used to create and publish releases. 4 | 5 | **Requirement:** Valid Apple developer certificate matching the prefix `Mac Developer:` in your keychain. 6 | 7 | Step-by step: 8 | 9 | 1. Run `release-build.sh` and copy the ARCHIVE_PATH printed to on stdout 10 | 2. Run `release-addchangelog.sh ARCHIVE_PATH` 11 | 3. Edit changelog.xml to contain suitable release notes 12 | 4. Run `release-publish.sh ARCHIVE_PATH` 13 | -------------------------------------------------------------------------------- /js-env-research/7qBmLkcUE_k.js: -------------------------------------------------------------------------------- 1 | if (self.CavalryLogger) { 2 | CavalryLogger.start_js([ "J7lEz" ]); 3 | } 4 | 5 | __d("ArtilleryReporting", [ "Artillery", "Banzai" ], function(a, b, c, d, e, f, g, h) { 6 | b.__markCompiled && b.__markCompiled(); 7 | var i = "artillery_javascript_trace", j = false; 8 | e.exports.init = function() { 9 | if (j) return; 10 | j = true; 11 | g.addRetroactiveListener("posttrace", function(k) { 12 | h.post(i, k, { 13 | retry: true, 14 | delay: 30 * 1e3 15 | }); 16 | }); 17 | }; 18 | }, null); -------------------------------------------------------------------------------- /Messenger/JSObjWrapper.m: -------------------------------------------------------------------------------- 1 | #import "JSObjWrapper.h" 2 | 3 | @implementation JSObjWrapper { 4 | JSGlobalContextRef _ctx; 5 | JSObjectRef _obj; 6 | } 7 | - (instancetype)initWithJSContext:(JSContextRef)ctx object:(JSObjectRef)obj { 8 | _ctx = JSContextGetGlobalContext(ctx); 9 | JSValueProtect(_ctx, obj); 10 | _obj = obj; 11 | return self; 12 | } 13 | - (JSContextRef)jsctx { 14 | return _ctx; 15 | } 16 | - (JSObjectRef)jsobj { 17 | return _obj; 18 | } 19 | - (void)dealloc { 20 | JSValueUnprotect(_ctx, _obj); 21 | } 22 | @end -------------------------------------------------------------------------------- /xcode-config/messenger.xcconfig: -------------------------------------------------------------------------------- 1 | PRODUCT_NAME = Messenger 2 | 3 | SDKROOT = macosx // aka "latest" 4 | MACOSX_DEPLOYMENT_TARGET = 10.9 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks 6 | 7 | INFOPLIST_FILE = Messenger/Info.plist 8 | 9 | GCC_PRECOMPILE_PREFIX_HEADER = YES 10 | GCC_PREFIX_HEADER = Messenger/Prefix.pch 11 | 12 | //SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PRODUCT_NAME)/BridgingHeader.h 13 | //OTHER_LDFLAGS = $(inherited) 14 | 15 | //CODE_SIGN_IDENTITY = Mac Developer 16 | 17 | SYMROOT = $(SRCROOT)/build 18 | -------------------------------------------------------------------------------- /admin/dist/addchangelog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | if [ "$1" = "" ]; then echo "Usage: $0 " >&2; exit 1; fi 4 | 5 | pushd "$(dirname "$0")/.." >/dev/null 6 | SRCDIR="$(dirname "$(pwd)")" 7 | popd >/dev/null 8 | 9 | ARCHIVE=$1 10 | 11 | python "${SRCDIR}/admin/dist/addchangelog.py" "$ARCHIVE" 12 | 13 | if (which subl) >/dev/null; then 14 | subl "${SRCDIR}"/changelog.xml:12:15 15 | else 16 | echo "A new entry has been added to the changelog." 17 | echo "You should add/update release notes:" 18 | echo " $EDITOR '${SRCDIR}/changelog.xml'" 19 | fi 20 | 21 | 22 | echo "Next step:" 23 | echo " admin/dist/publish.sh ${ARCHIVE}" 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | 3 | .DS_Store 4 | *.log 5 | *.sock* 6 | *.pyo 7 | *.pyc 8 | *.crash 9 | *.so 10 | *.o 11 | *.a 12 | * copy.* 13 | ._* 14 | build_config.mk 15 | *.patch 16 | *.diff 17 | 18 | *.xcodeproj/*.pbxuser 19 | *.xcodeproj/*.perspective* 20 | *.xcodeproj/*.mode1* 21 | */*.xcodeproj/*.pbxuser 22 | */*.xcodeproj/*.perspective* 23 | */*.xcodeproj/*.mode1* 24 | */*/*.xcodeproj/*.pbxuser 25 | */*/*.xcodeproj/*.perspective* 26 | */*/*.xcodeproj/*.mode1* 27 | 28 | *.xcodeproj/xcuserdata 29 | *.xcodeproj/project.xcworkspace 30 | */*.xcodeproj/xcuserdata 31 | */*.xcodeproj/project.xcworkspace 32 | */*/*.xcodeproj/xcuserdata 33 | */*/*.xcodeproj/project.xcworkspace 34 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 13 | // there are name-space collisions) so we can list all of them to start with: 14 | 15 | #import 16 | 17 | #import 18 | #import 19 | #import 20 | #import 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | /*! 13 | Applies special display formatting to version numbers. 14 | */ 15 | @protocol SUVersionDisplay 16 | 17 | /*! 18 | Formats two version strings. 19 | 20 | Both versions are provided so that important distinguishing information 21 | can be displayed while also leaving out unnecessary/confusing parts. 22 | */ 23 | - (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | @protocol SUAppcastDelegate; 13 | 14 | @class SUAppcastItem; 15 | @interface SUAppcast : NSObject 16 | 17 | @property (weak) id delegate; 18 | @property (copy) NSString *userAgentString; 19 | 20 | - (void)fetchAppcastFromURL:(NSURL *)url; 21 | 22 | @property (readonly, copy) NSArray *items; 23 | @end 24 | 25 | @protocol SUAppcastDelegate 26 | - (void)appcastDidFinishLoading:(SUAppcast *)appcast; 27 | - (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #import 13 | 14 | /*! 15 | Provides version comparison facilities for Sparkle. 16 | */ 17 | @protocol SUVersionComparison 18 | 19 | /*! 20 | An abstract method to compare two version strings. 21 | 22 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 23 | and NSOrderedSame if they are equivalent. 24 | */ 25 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 26 | 27 | @end 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Messenger/jsapi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #import 3 | #import 4 | 5 | #define U16JSStr(p) JSStringCreateWithCharacters((const JSChar*)p, std::char_traits::length(p)) 6 | 7 | JSObjectRef JSNotificationsCreate(JSContextRef, size_t argc, const JSValueRef argv[], JSValueRef* exc); 8 | NSString* JSNotificationsAddNotification(JSContextRef ctx, JSObjectRef obj, JSValueRef* exc); 9 | BOOL JSNotificationsActivateNotification(JSContextRef ctx, NSUserNotification* notif); 10 | 11 | JSClassRef JSNotificationJSClass(); 12 | JSObjectRef JSNotificationConstruct(JSContextRef, JSObjectRef, size_t argc, const JSValueRef argv[], JSValueRef* exc); 13 | JSObjectRef JSNotificationCreate(JSContextRef, size_t argc, const JSValueRef argv[], JSValueRef* exc); 14 | BOOL JSNotificationDidActivate(JSContextRef ctx, JSObjectRef obj, NSUserNotification* notif); 15 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | 13 | #import "SUVersionComparisonProtocol.h" 14 | 15 | /*! 16 | Sparkle's default version comparator. 17 | 18 | This comparator is adapted from MacPAD, by Kevin Ballard. 19 | It's "dumb" in that it does essentially string comparison, 20 | in components split by character type. 21 | */ 22 | @interface SUStandardVersionComparator : NSObject 23 | 24 | /*! 25 | Returns a singleton instance of the comparator. 26 | */ 27 | + (SUStandardVersionComparator *)defaultComparator; 28 | 29 | /*! 30 | Compares version strings through textual analysis. 31 | 32 | See the implementation for more details. 33 | */ 34 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 35 | @end 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /js-env-research/KzPBZimeKDr.js: -------------------------------------------------------------------------------- 1 | if (self.CavalryLogger) { 2 | CavalryLogger.start_js([ "4vv8/" ]); 3 | } 4 | 5 | __d("TimeSpentBitArrayLogger", [ "Arbiter", "Banzai", "BanzaiODS", "TimeSpentArray", "TimeSpentConfig", "TimeSpentImmediateActiveSecondsLogger", "UserActivity", "copyProperties", "isInIframe" ], function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) { 6 | b.__markCompiled && b.__markCompiled(); 7 | var p = { 8 | delay: h.BASIC.delay, 9 | retry: true 10 | }; 11 | function q(r, s) { 12 | if (h.isEnabled("time_spent_bit_array")) { 13 | g.inform("timespent/tosbitdataposted", n({}, r)); 14 | if (typeof s == "number") { 15 | p.delay = s; 16 | } else p.delay = h.BASIC.delay; 17 | h.post("time_spent_bit_array", n({}, r), p); 18 | p.delay = k.delay; 19 | } 20 | } 21 | e.exports = { 22 | init: function(r) { 23 | if (o()) return; 24 | m.subscribe(function(t, u) { 25 | var v = u.last_inform; 26 | j.update(v); 27 | l.maybeReportActiveSecond(v); 28 | }); 29 | var s = Date.now(); 30 | j.init(q, k, s); 31 | l.maybeReportActiveSecond(s); 32 | i.bumpEntityKey("ms.time_spent.qa.www", "time_spent.bits.js_initialized"); 33 | } 34 | }; 35 | }, null); -------------------------------------------------------------------------------- /Messenger/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "128x128", 25 | "idiom" : "mac", 26 | "filename" : "icon-128.png", 27 | "scale" : "1x" 28 | }, 29 | { 30 | "idiom" : "mac", 31 | "size" : "128x128", 32 | "scale" : "2x" 33 | }, 34 | { 35 | "idiom" : "mac", 36 | "size" : "256x256", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "idiom" : "mac", 41 | "size" : "256x256", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "idiom" : "mac", 46 | "size" : "512x512", 47 | "scale" : "1x" 48 | }, 49 | { 50 | "idiom" : "mac", 51 | "size" : "512x512", 52 | "scale" : "2x" 53 | } 54 | ], 55 | "info" : { 56 | "version" : 1, 57 | "author" : "xcode" 58 | } 59 | } -------------------------------------------------------------------------------- /admin/README.md: -------------------------------------------------------------------------------- 1 | # Dev administration 2 | 3 | 4 | ## Source dependencies 5 | 6 | This project uses *git subtree* for managing dependencies via the porcelain program "admin/dep." 7 | 8 | Listing dependencies: 9 | 10 | admin/dep ls 11 | 12 | Adding a dependency named "foo" into directory "a/foo", tracking the master branch of some repo: 13 | 14 | admin/dep add foo a/foo git@github.com:bar/foo.git master 15 | 16 | Updating a dependency: 17 | 18 | admin/dep update foo 19 | 20 | Removing: 21 | 22 | # remove the foo entry in ./deps, then 23 | git remote remove foo 24 | git rm a/foo 25 | git commit ... 26 | 27 | 28 | ## Distribution 29 | 30 | The `dist/*` scripts are used to create and publish releases. 31 | 32 | **Requirement:** 33 | - Valid Apple developer certificate matching the prefix `Mac Developer` in your keychain. 34 | - Amazon AWS CLI tools (`pip install awscli`) 35 | 36 | 1. Run `dist/build.sh` and copy the ARCHIVE_PATH printed to on stdout 37 | 2. Run `dist/addchangelog.sh ARCHIVE_PATH` 38 | 3. Edit dist/changelog.xml to contain suitable release notes 39 | 4. Run `dist/publish.sh ARCHIVE_PATH` 40 | 41 | Finally you should git tag. The different commands will print "what to do next" instructions when they complete. 42 | -------------------------------------------------------------------------------- /admin/dist/update-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | cd "$(dirname "$0")/../.." 4 | 5 | if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then 6 | echo "Usage: $0 [--quiet | --help]" >&2 7 | exit 1 8 | fi 9 | 10 | INFO_PLIST=Messenger/Info.plist 11 | RELEASE_VERSION=$(cat version.txt) 12 | SOURCE_VERSION=$(git rev-parse HEAD) 13 | SOURCE_MTIME=$(git log '--format=%ct' -n1) 14 | VERSION="${RELEASE_VERSION}.${SOURCE_MTIME}" 15 | 16 | plistb=/usr/libexec/PlistBuddy 17 | 18 | CURR_VERSION=$($plistb -c 'Print :CFBundleVersion' $INFO_PLIST) 19 | 20 | if [ "$CURR_VERSION" = "${VERSION}" ]; then 21 | if [ "$1" != "--quiet" ]; then 22 | echo 'Version info in Info.plist is already up-to date.' 23 | fi 24 | else 25 | $plistb -c "Set :CFBundleShortVersionString '${RELEASE_VERSION}'" $INFO_PLIST 26 | $plistb -c "Set :CFBundleVersion '${VERSION}'" $INFO_PLIST 27 | $plistb -c "Set :GitRev '${SOURCE_VERSION}'" $INFO_PLIST 28 | 29 | if [ "$1" != "--quiet" ]; then 30 | echo -n 'M GitRev=' 31 | $plistb -c 'Print :GitRev' $INFO_PLIST 32 | echo -n 'M CFBundleVersion=' 33 | $plistb -c 'Print :CFBundleVersion' $INFO_PLIST 34 | echo -n 'M CFBundleShortVersionString=' 35 | fi 36 | fi 37 | 38 | $plistb -c 'Print :CFBundleVersion' $INFO_PLIST 39 | -------------------------------------------------------------------------------- /Messenger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | icon 11 | CFBundleIdentifier 12 | me.rsms.fbmessenger 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.0.4 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.0.4.1428634580 25 | GitRev 26 | a80cddf5538e66d6d04e829126cb90b51d0556c0 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | NSHumanReadableCopyright 30 | Copyright © 2015 Rsms. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | FBMApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 14A298i 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Sparkle 11 | CFBundleIdentifier 12 | org.andymatuschak.Sparkle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Sparkle 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.8.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0b186dc 25 | DTCompiler 26 | com.apple.compilers.llvm.clang.1_0 27 | DTPlatformBuild 28 | 6A254o 29 | DTPlatformVersion 30 | GM 31 | DTSDKBuild 32 | 14A283h 33 | DTSDKName 34 | macosx10.10 35 | DTXcode 36 | 0600 37 | DTXcodeBuild 38 | 6A254o 39 | 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Messenger 2 | 3 | Mac app wrapper around [Facebook's stand-alone Messenger](https://www.messenger.com/). 4 | 5 | ![fb-messenger](https://dl.dropboxusercontent.com/u/1603978/fb-messenger.png) 6 | 7 | > Disclaimer: This is NOT an official Facebook product, but just a hobby project 8 | 9 | Icon courtesy of Sebastiaan de With (Muir v3) 10 | 11 | ## MIT license 12 | 13 | Copyright (c) 2015 Authors of the source code of this project 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | @interface SUAppcastItem : NSObject 13 | @property (copy, readonly) NSString *title; 14 | @property (copy, readonly) NSDate *date; 15 | @property (copy, readonly) NSString *itemDescription; 16 | @property (strong, readonly) NSURL *releaseNotesURL; 17 | @property (copy, readonly) NSString *DSASignature; 18 | @property (copy, readonly) NSString *minimumSystemVersion; 19 | @property (copy, readonly) NSString *maximumSystemVersion; 20 | @property (strong, readonly) NSURL *fileURL; 21 | @property (copy, readonly) NSString *versionString; 22 | @property (copy, readonly) NSString *displayVersionString; 23 | @property (copy, readonly) NSDictionary *deltaUpdates; 24 | @property (strong, readonly) NSURL *infoURL; 25 | 26 | // Initializes with data from a dictionary provided by the RSS class. 27 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 28 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; 29 | 30 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; 31 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; 32 | 33 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 34 | @property (readonly, copy) NSDictionary *propertiesDictionary; 35 | 36 | - (NSURL *)infoURL; 37 | 38 | @end 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /xcode-config/common.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_SEARCH_USER_PATHS = NO 2 | // If enabled both #include -style and #include "header.h"-style directives will 3 | // search the paths in "User Header Search Paths" before "Header Search Paths", with the 4 | // consequence that user headers (such as your own String.h header) would have precedence 5 | // over system headers when using #include . This is done using the -iquote flag 6 | // for the paths provided in "User Header Search Paths". If disabled and your compiler fully 7 | // supports separate user paths, user headers will only be accessible with 8 | // #include "header.h"-style preprocessor directives. 9 | 10 | GCC_SYMBOLS_PRIVATE_EXTERN = NO 11 | // When enabled, all symbols are declared 'private extern' unless explicitly marked to be 12 | // exported using '__attribute__((visibility("default")))' in code. If not enabled, all symbols 13 | // are exported unless explicitly marked as 'private extern'. 14 | 15 | GCC_C_LANGUAGE_STANDARD = gnu11 16 | CLANG_CXX_LANGUAGE_STANDARD = c++14 17 | CLANG_CXX_LIBRARY = libc++ 18 | GCC_ENABLE_CPP_RTTI = NO 19 | GCC_ENABLE_CPP_EXCEPTIONS = YES 20 | 21 | CLANG_ENABLE_OBJC_ARC = YES 22 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 23 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR 24 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR 25 | ENABLE_STRICT_OBJC_MSGSEND = YES 26 | GCC_WARN_UNDECLARED_SELECTOR = YES 27 | GCC_ENABLE_OBJC_EXCEPTIONS = YES 28 | 29 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES 30 | GCC_WARN_ABOUT_RETURN_TYPE = YES 31 | GCC_WARN_MISSING_PARENTHESES = YES 32 | GCC_WARN_UNUSED_VARIABLE = YES 33 | WARNING_CFLAGS = -Wall 34 | 35 | CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer 36 | -------------------------------------------------------------------------------- /admin/dist/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # usage build.sh [-f] 4 | # -f Force rebuild 5 | # 6 | # Produces: 7 | # build/{Debug,Release}/App-M.m.r-githash.zip (.app) 8 | # build/{Debug,Release}/App-M.m.r-githash.dwarf.zip 9 | # 10 | set -e 11 | cd "$(dirname "$0")/../.." 12 | 13 | PROJ=Messenger 14 | 15 | BUILD_DIR=$(pwd)/build 16 | BUILD_CONFIG=Release 17 | PRODUCT_DIR=${BUILD_DIR}/${BUILD_CONFIG} 18 | APP_NAME=${PROJ}.app 19 | APP_BUNDLE=${PRODUCT_DIR}/${APP_NAME} 20 | VERSION=$($SHELL admin/dist/update-version.sh --quiet) 21 | GIT_HASH=$(git rev-parse --short=16 HEAD) 22 | ARCHIVE=${PROJ}-${VERSION}-${GIT_HASH}.zip 23 | 24 | if [ "$1" = "-f" ]; then 25 | rm -rf "${APP_BUNDLE}" "${BUILD_DIR}/${PROJ}.build/${BUILD_CONFIG}" 26 | fi 27 | 28 | xcodebuild -project ${PROJ}.xcodeproj -target ${PROJ} -configuration ${BUILD_CONFIG} \ 29 | CODE_SIGN_IDENTITY="" \ 30 | CODE_SIGNING_REQUIRED=NO \ 31 | GCC_PREPROCESSOR_DEFINITIONS='$(inherited) DISABLE_UNIT_TESTS=1' 32 | 33 | echo 'Signing' 34 | # See https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/DistributingApplicationsOutside/DistributingApplicationsOutside.html 35 | /usr/bin/codesign --force --sign 'Developer ID Application' --deep "${APP_BUNDLE}" 36 | 37 | pushd "${PRODUCT_DIR}" >/dev/null 38 | zip -r -q --symlinks "${ARCHIVE}" "${APP_NAME}" 39 | pushd "${APP_NAME}.dSYM/Contents/Resources/DWARF" >/dev/null 40 | mv "${PROJ}" "${PROJ}-${VERSION}.dwarf" 41 | zip -r -q "../../../../${PROJ}-${VERSION}-${GIT_HASH}.dwarf.zip" "${PROJ}-${VERSION}.dwarf" 42 | popd >/dev/null 43 | popd >/dev/null 44 | 45 | echo "Next step:" 46 | echo " admin/dist/addchangelog.sh ${BUILD_DIR}/${BUILD_CONFIG}/${ARCHIVE}" 47 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 14A298i 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | Autoupdate 11 | CFBundleIconFile 12 | AppIcon 13 | CFBundleIdentifier 14 | org.sparkle-project.Sparkle.Autoupdate 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.8.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.8.0 25 | DTCompiler 26 | com.apple.compilers.llvm.clang.1_0 27 | DTPlatformBuild 28 | 6A254o 29 | DTPlatformVersion 30 | GM 31 | DTSDKBuild 32 | 14A283h 33 | DTSDKName 34 | macosx10.10 35 | DTXcode 36 | 0600 37 | DTXcodeBuild 38 | 6A254o 39 | LSBackgroundOnly 40 | 1 41 | LSMinimumSystemVersion 42 | 10.7 43 | LSUIElement 44 | 1 45 | NSMainNibFile 46 | MainMenu 47 | NSPrincipalClass 48 | NSApplication 49 | 50 | 51 | -------------------------------------------------------------------------------- /admin/dist/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | S3_HOSTNAME=fbmacmessenger.rsms.me 5 | 6 | if ! [ -f "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then 7 | echo "Publish a release." >&2 8 | echo "Usage: $0 " >&2 9 | exit 1 10 | fi 11 | 12 | pushd "$(dirname "$0")/.." >/dev/null 13 | SRCDIR="$(dirname "$(pwd)")" 14 | popd >/dev/null 15 | 16 | ARCHIVE=$1 17 | ARCHIVE_BASENAME=$(basename "$ARCHIVE") 18 | PROJ=$(echo "${ARCHIVE_BASENAME}" | sed -E 's/^([^\-]+)\-.+/\1/') 19 | VERSION=$(echo "${ARCHIVE_BASENAME}" | sed -E 's/^.+\-([0-9\.]+)\-[0-9A-Fa-f]+\.zip$/\1/') 20 | RELEASE_VERSION=$(echo "${ARCHIVE_BASENAME}" | sed -E 's/^.+\-([0-9]+\.[0-9]+\.[0-9]+).+/\1/') 21 | VERSION_TIMESTAMP=$(echo "${ARCHIVE_BASENAME}" | sed -E 's/^.+\-[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+).+/\1/') 22 | VERSION_DATETIME=$(date -r $VERSION_TIMESTAMP -u "+%Y-%m-%d_%H-%M-%S") 23 | GIT_REV=$(echo "${ARCHIVE_BASENAME}" | sed -E 's/^.+\-([0-9A-Fa-f]+)\.zip$/\1/') 24 | DWARF_BASENAME=$(basename -s .zip "$ARCHIVE_BASENAME").dwarf.zip 25 | DWARF_FILE=$(dirname "$ARCHIVE")/$DWARF_BASENAME 26 | 27 | if grep --quiet 'sparkle:version="'"${VERSION}"'"' "changelog.xml"; then 28 | 29 | source admin/aws-credentials.sh 30 | 31 | aws s3 cp "$DWARF_FILE" "s3://${S3_HOSTNAME}/dsym/${DWARF_BASENAME}" 32 | aws s3 cp "$ARCHIVE" "s3://${S3_HOSTNAME}/dist/${ARCHIVE_BASENAME}" 33 | aws s3 cp "changelog.xml" "s3://${S3_HOSTNAME}/changelog.xml" 34 | aws s3 cp "admin/dist/index.html" "s3://${S3_HOSTNAME}/index.html" 35 | 36 | else 37 | echo "Version ${VERSION} not found in changelog.xml — did you run addchangelog?" >&2 38 | echo " $(dirname "$0")/addchangelog.sh '$ARCHIVE'" >&2 39 | exit 1 40 | fi 41 | 42 | echo "You should tag the release and commit the modified version:" 43 | echo -n " git commit -m 'Version ${RELEASE_VERSION} release ${VERSION_DATETIME}' " 44 | echo "changelog.xml version.txt Messenger/Info.plist" 45 | echo " git tag v${RELEASE_VERSION}.${VERSION_DATETIME} \$(git log -n1 '--format=%H')" 46 | echo " git push origin master --tags" 47 | -------------------------------------------------------------------------------- /Messenger/WebPreferences.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | @interface WebPreferences (Private) 4 | @property (nonatomic) BOOL acceleratedCompositingEnabled; 5 | @property (nonatomic) BOOL acceleratedDrawingEnabled; 6 | @property (nonatomic) BOOL accelerated2dCanvasEnabled; 7 | @property (nonatomic) BOOL showDebugBorders; 8 | @property (nonatomic) BOOL showRepaintCounter; 9 | @property (nonatomic) BOOL developerExtrasEnabled; 10 | @property (nonatomic) BOOL localStorageEnabled; 11 | @property (nonatomic) BOOL databasesEnabled; 12 | @property (nonatomic) BOOL notificationsEnabled; 13 | @property (nonatomic) BOOL offlineWebApplicationCacheEnabled; 14 | @property (nonatomic) BOOL webGLEnabled; 15 | @property (nonatomic) BOOL multithreadedWebGLEnabled; 16 | @property (nonatomic) BOOL webAudioEnabled; 17 | @property (nonatomic) BOOL usesEncodingDetector; 18 | @property (nonatomic) BOOL usePreHTML5ParserQuirks; 19 | @property (nonatomic) BOOL useLegacyTextAlignPositionedElementBehavior; 20 | @property (nonatomic) BOOL textAreasAreResizable; 21 | @property (nonatomic) BOOL subpixelCSSOMElementMetricsEnabled; 22 | @property (nonatomic) BOOL mediaPlaybackRequiresUserGesture; 23 | @property (nonatomic) BOOL mediaPlaybackAllowsInline; 24 | @property (nonatomic, getter=isXSSAuditorEnabled) BOOL XSSAuditorEnabled; 25 | @property (nonatomic, getter=isWebSecurityEnabled) BOOL WebSecurityEnabled; 26 | @property (nonatomic, getter=isHixie76WebSocketProtocolEnabled) BOOL hixie76WebSocketProtocolEnabled; 27 | @property (nonatomic, getter=isFrameFlatteningEnabled) BOOL frameFlatteningEnabled; 28 | @property (nonatomic, getter=isDNSPrefetchingEnabled) BOOL DNSPrefetchingEnabled; 29 | @property (nonatomic) BOOL hyperlinkAuditingEnabled; 30 | @property (nonatomic) BOOL hiddenPageCSSAnimationSuspensionEnabled; 31 | @property (nonatomic) BOOL hiddenPageDOMTimerThrottlingEnabled; 32 | @property (nonatomic) BOOL fullScreenEnabled; 33 | @property (nonatomic) BOOL diagnosticLoggingEnabled; 34 | @property (nonatomic) BOOL cssCompositingEnabled; 35 | @property (nonatomic) BOOL cssRegionsEnabled; 36 | @property (nonatomic) BOOL backspaceKeyNavigationEnabled; 37 | @property (nonatomic) BOOL asynchronousSpellCheckingEnabled; 38 | @property (nonatomic) BOOL zoomsTextOnly; 39 | @property (nonatomic) BOOL mockScrollbarsEnabled; 40 | - (void)_setLocalStorageDatabasePath:(NSString*)path; 41 | @end 42 | -------------------------------------------------------------------------------- /admin/dist/addchangelog.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import sys, re, os, time, subprocess 3 | 4 | if len(sys.argv) < 2: 5 | print >> sys.stderr, 'usage: '+sys.argv[0]+' ' 6 | sys.exit(1) 7 | 8 | filepath = sys.argv[1] 9 | filename = os.path.basename(filepath) 10 | filestat = os.stat(filepath) 11 | 12 | version, version_release, timestamp, git_hash =\ 13 | re.findall(r'\-(([0-9]+\.[0-9]+\.[0-9]+)\.([0-9]+))\-([0-9A-Fa-f]+)\.zip$', filename)[0] 14 | 15 | itembuf = ''' 16 | 17 | Messenger for Mac {version_release} 18 | 20 | {changes} 21 | 22 | ]]> 23 | {pubdate} 24 | 10.9 25 | 31 | 32 | ''' 33 | 34 | # Load changelog 35 | changelogFilename =\ 36 | os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/changelog.xml' 37 | with open(changelogFilename, 'r') as f: 38 | buf = f.read() 39 | 40 | # Make sure this version isn't in the changelog already 41 | if version in re.findall(r'sparkle:version="([0-9\.]+)\-', buf): 42 | print >> sys.stderr, ('Version %s is already in %s -- you need to manually '\ 43 | 'remove it and re-run this script.') % (version, changelogFilename) 44 | sys.exit(1) 45 | 46 | changes = '
  • Initial release
  • ' 47 | 48 | # find previous version's git hash 49 | newGitHash = git_hash 50 | prevGitHash = re.findall(r'gitrev="([0-9A-Fa-f]+)"', buf) 51 | if len(prevGitHash) != 0: 52 | prevGitHash = prevGitHash[0] 53 | 54 | # extract git log since last version 55 | gitlog = subprocess.check_output( 56 | "git log "+prevGitHash+'..'+newGitHash+' --no-merges --date-order --notes --oneline', 57 | shell=True) 58 | changes = '' 59 | for line in gitlog.strip().split("\n"): 60 | changes += '
  • ' + line + '
  • \n' 61 | 62 | # Format item template 63 | mtime = time.localtime(filestat.st_mtime) 64 | pubdate = time.strftime("%a, %d %b %G %T %z", mtime) 65 | itembuf = itembuf.format( 66 | version=version, 67 | version_release=version_release, 68 | gitrev=git_hash, 69 | pubdate=pubdate, 70 | filesize=filestat.st_size, 71 | filename=filename, 72 | changes=changes.rstrip()) 73 | 74 | if buf.find('') != -1: 75 | buf = re.compile(r'(\n[ \r\n\t]*)', re.M).sub(itembuf.rstrip() + r'\1', buf, 1) 76 | else: 77 | buf = re.compile(r'(\n[ \r\n\t]*)', re.M).sub(itembuf.rstrip() + r'\1', buf, 1) 78 | 79 | with open(changelogFilename, 'w') as f: 80 | f.write(buf) 81 | -------------------------------------------------------------------------------- /sparkle/LICENSE: -------------------------------------------------------------------------------- 1 | © 2006-2013 Andy Matuschak 2 | © 2009-2013 Elgato Systems GmbH. 3 | © 2011-2014 Kornel Lesiński 4 | © 2014 C.W. Betts 5 | © 2014 Petroules Corporation, Sparkle Project contributors 6 | © 2014 Big Nerd Ranch 7 | All rights reserved. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 13 | the Software, and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 21 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 22 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 23 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | ================= 27 | EXTERNAL LICENSES 28 | ================= 29 | 30 | bspatch.c and bsdiff.c, from bsdiff 4.3 : © 2003-2005 Colin Percival. 31 | SUDSAVerifier.m: © 2011 Mark Hamlin. 32 | 33 | All rights reserved. 34 | 35 | Redistribution and use in source and binary forms, with or without 36 | modification, are permitted providing that the following conditions 37 | are met: 38 | 1. Redistributions of source code must retain the above copyright 39 | notice, this list of conditions and the following disclaimer. 40 | 2. Redistributions in binary form must reproduce the above copyright 41 | notice, this list of conditions and the following disclaimer in the 42 | documentation and/or other materials provided with the distribution. 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 45 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 46 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 48 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 52 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 53 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54 | POSSIBILITY OF SUCH DAMAGE. 55 | -------------------------------------------------------------------------------- /Messenger/JSNotifications.js.mm: -------------------------------------------------------------------------------- 1 | #import "jsapi.h" 2 | #import "JSClass.hh" 3 | #import "JSObjWrapper.h" 4 | #import 5 | #import 6 | 7 | 8 | // Note: "user notifications" in OS X can be activated at any point in time, even across app launches. 9 | // We don't support "across app launches" (because Messenger associates a javascript onclick function 10 | // with notifications.) 11 | 12 | // Note: NSUserNotifcation can not be extended and it is actually serialized and is not just residing 13 | // in memory. Therefore we maintain a dictionary of notification identifiers => javascript objects, 14 | // where the javascript object is a window.Notification object (JSNotification.) 15 | 16 | 17 | struct JSNotifications : JSClass { 18 | 19 | JSNotifications() { 20 | _notifs = [NSMutableDictionary new]; 21 | } 22 | 23 | 24 | NSString* addNotification(JSObjectRef obj, JSValueRef* exc) { 25 | //NSLog(@"JSNotifications.addNotification()"); 26 | auto jsobjwrapper = [[JSObjWrapper alloc] initWithJSContext:jsctx object:obj]; 27 | auto identifier = [NSString stringWithFormat:@"n%f", [NSDate date].timeIntervalSinceReferenceDate]; 28 | _notifs[identifier] = jsobjwrapper; 29 | return identifier; 30 | } 31 | 32 | 33 | BOOL activateNotification(NSUserNotification* notif) { 34 | //NSLog(@"JSNotifications.activateNotification()"); 35 | JSObjWrapper* ow = _notifs[notif.identifier]; 36 | if (ow == nil) { return NO; } 37 | assert([ow isKindOfClass:[JSObjWrapper class]]); 38 | return JSNotificationDidActivate(ow.jsctx, ow.jsobj, notif); 39 | } 40 | 41 | 42 | NSMutableDictionary* _notifs; 43 | 44 | }; 45 | 46 | 47 | static JSNotifications* _JSNotificationsGet(JSContextRef ctx, JSValueRef* exc) { 48 | auto globalObj = JSContextGetGlobalObject(ctx); 49 | assert(globalObj != nullptr); 50 | auto v = JSClass::getProperty(ctx, globalObj, u"_notifications", exc); 51 | if (v == nullptr){ 52 | return nullptr; 53 | } 54 | auto obj = JSValueToObject(ctx, v, exc); 55 | if (obj == nullptr) { 56 | return nullptr; 57 | } 58 | auto p = (JSNotifications*)JSObjectGetPrivate(obj); 59 | if (p == nullptr) { 60 | if (exc != nullptr) { 61 | *exc = JSClass::createJSError(ctx, u"method called on unexpected \"this\" object"); 62 | } 63 | } 64 | return p; 65 | } 66 | 67 | 68 | NSString* JSNotificationsAddNotification(JSContextRef ctx, JSObjectRef obj, JSValueRef* exc) { 69 | auto notifs = _JSNotificationsGet(ctx, exc); 70 | if (!notifs) { 71 | return nullptr; 72 | } 73 | return notifs->addNotification(obj, exc); 74 | } 75 | 76 | 77 | BOOL JSNotificationsActivateNotification(JSContextRef ctx, NSUserNotification* notif) { 78 | //NSLog(@"JSNotificationsActivateNotification()"); 79 | auto n = _JSNotificationsGet(ctx, nullptr); 80 | return (n != nullptr) ? n->activateNotification(notif) : NO; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /admin/dep: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | if [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "" ]; then 4 | echo "usage:" >&2 5 | echo " $0 list" >&2 6 | echo " $0 update ..." >&2 7 | echo " $0 add " >&2 8 | echo " $0 push ..." >&2 9 | exit 1 10 | fi 11 | 12 | cd "$(dirname "$0")/.." 13 | 14 | mget() { 15 | local array=$1 index=$2 16 | local i="${array}_$index" 17 | printf '%s' "${!i}" 18 | } 19 | 20 | deps=() 21 | 22 | # Load deps 23 | while read line; do 24 | # echo "line: $line" 25 | if [[ $line != '#'* ]] && [[ $line != '' ]]; then 26 | eval $(echo $line | sed -E 's/([^ ]+)[ ]+([^ ]+)[ ]+(.+)/name="\1"; branch="\2"; path="\3"/') 27 | deps+=($name $branch $path) 28 | declare "branches_$name=$branch" 29 | declare "paths_$name=$path" 30 | if [ "$1" = "list" ] || [ "$1" = "ls" ]; then 31 | url=$(git remote -v | grep -E '^'$name'\s+.*\(fetch\)' | awk '{print $2}') 32 | echo "$name in './$path' tracking $url @ $branch" 33 | fi 34 | fi 35 | done < deps 36 | 37 | use_dep() { 38 | for ((a=0, b=1, c=2; c <= ${#deps[@]} ; a+=3, b+=3, c+=3)); do 39 | if [ "${deps[$a]}" = "$1" ]; then 40 | name=${deps[$a]} 41 | branch=${deps[$b]} 42 | path=${deps[$c]} 43 | return 0 44 | fi 45 | done 46 | return 1 47 | } 48 | 49 | 50 | if [ "$1" = "add" ]; then 51 | if [ $# -lt 5 ]; then 52 | echo "not enough arguments to '$1'. Try '$0 --help'" >&2 53 | exit 1 54 | fi 55 | 56 | name=$2; path=$3; url=$4; branch=$5 57 | 58 | if [ -e $path ]; then 59 | echo "directory '$path' already exists" >&2 60 | exit 1 61 | fi 62 | 63 | if use_dep $name; then 64 | echo "name '$name' is already being used" >&2 65 | exit 1 66 | fi 67 | 68 | echo git remote add -f $name "'$url'" 69 | git remote add -f $name "$url" 70 | 71 | echo git subtree add "'--prefix=$path'" $name "'$branch'" --squash 72 | if ! git subtree add "--prefix=$path" $name "$branch" --squash; then 73 | git remote remove $name 74 | exit 1 75 | fi 76 | 77 | printf '%-13s %-10s %s\n' $name "$branch" "$path" >> deps 78 | git commit -m "[dep] added $name to ./deps" deps 79 | 80 | elif [ "$1" = "update" ]; then 81 | for depname in ${@:2}; do 82 | if ! use_dep $depname; then 83 | echo "'$depname' not found in deps file" >&2 84 | exit 1 85 | fi 86 | 87 | echo git fetch "'$name'" "'$branch'" 88 | git fetch "$name" "$branch" 89 | 90 | echo git subtree pull "'--prefix=$path'" $name "'$branch'" --squash 91 | git subtree pull "--prefix=$path" $name "$branch" --squash 92 | done 93 | 94 | elif [ "$1" = "push" ]; then 95 | 96 | for depname in ${@:2}; do 97 | if ! use_dep $depname; then 98 | echo "'$depname' not found in deps file" >&2 99 | exit 1 100 | fi 101 | 102 | echo git subtree push "'--prefix=$path'" $name "'$branch'" 103 | git subtree push "--prefix=$path" $name "$branch" 104 | done 105 | 106 | elif [ "$1" != "list" ] && [ "$1" != "ls" ]; then 107 | echo "'$1' is not a command. Try '$0 --help'" >&2 108 | exit 1 109 | fi 110 | -------------------------------------------------------------------------------- /Messenger/JSNotification.js.mm: -------------------------------------------------------------------------------- 1 | #import "jsapi.h" 2 | #import "JSClass.hh" 3 | #import "JSObjWrapper.h" 4 | #import 5 | #import 6 | 7 | 8 | static JSStringRef kJSString_GRANTED; 9 | 10 | 11 | static void __attribute__((constructor))_init() { 12 | kJSString_GRANTED = U16JSStr(u"granted"); 13 | } 14 | 15 | 16 | struct JSNotification : JSClass { 17 | 18 | JSNotification() {} 19 | 20 | // Called just before JSNotification{Create,Construct} returns 21 | bool jsinit(size_t argc, const JSValueRef argv[], JSValueRef* exc) { 22 | // args: (p.title, {body: p.body, icon: p.icon, tag: p.tag}) 23 | //NSLog(@"JSNotification.jsinit()"); 24 | auto notif = [NSUserNotification new]; 25 | 26 | notif.title = argc > 0 ? JSClass::NSStringFromJSValue(jsctx, argv[0]) : nil; 27 | 28 | NSURL* iconURL = nil; 29 | 30 | if (argc > 1) { 31 | auto params = JSValueToObject(jsctx, argv[1], exc); 32 | if (!params) { 33 | return nullptr; 34 | } 35 | 36 | auto bodyv = JSClass::tryGetProperty(jsctx, params, u"body"); 37 | if (JSValueIsString(jsctx, bodyv)) { 38 | notif.informativeText = JSClass::NSStringFromJSValue(jsctx, bodyv, exc); 39 | if (notif.informativeText == nullptr) { 40 | return nullptr; 41 | } 42 | } 43 | 44 | auto iconv = JSClass::tryGetProperty(jsctx, params, u"icon"); 45 | if (JSValueIsString(jsctx, bodyv)) { 46 | auto icons = JSClass::NSStringFromJSValue(jsctx, iconv, exc); 47 | if (icons != nullptr) { 48 | iconURL = [NSURL URLWithString:icons]; 49 | } 50 | } 51 | } 52 | 53 | notif.soundName = NSUserNotificationDefaultSoundName; 54 | notif.userInfo = @{@"isJSNotification": @(YES)}; 55 | notif.identifier = JSNotificationsAddNotification(jsctx, jsobj, exc); 56 | 57 | if (iconURL != nullptr) { 58 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 59 | notif.contentImage = [[NSImage alloc] initWithContentsOfURL:iconURL]; 60 | dispatch_async(dispatch_get_main_queue(), ^{ 61 | [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:notif]; 62 | }); 63 | }); 64 | } else { 65 | [[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:notif]; 66 | } 67 | 68 | return true; 69 | } 70 | 71 | //.onclick = p.onClick; 72 | //.onclose = function() {}; 73 | 74 | JSValueRef jsget_permission(JSValueRef* exc) { 75 | return JSValueMakeString(jsctx, kJSString_GRANTED); 76 | } 77 | 78 | JSValueRef jscall_requestPermission(size_t argc, const JSValueRef argv[], JSValueRef* exc) { 79 | //NSLog(@"JSNotification.requestPermission()"); 80 | return JSValueMakeUndefined(jsctx); 81 | } 82 | 83 | JSValueRef jscall_close(size_t argc, const JSValueRef argv[], JSValueRef* exc) { 84 | //NSLog(@"JSNotification.close()"); 85 | // TODO implementation 86 | return JSValueMakeUndefined(jsctx); 87 | } 88 | 89 | 90 | BOOL didActivate(NSUserNotification* notif) { 91 | //NSLog(@"JSNotification.didActivate()"); 92 | auto v = tryGetProperty(jsctx, jsobj, u"onclick"); 93 | if (v == nullptr || !JSValueIsObject(jsctx, v)) { 94 | v = tryGetProperty(jsctx, jsobj, u"onClick"); 95 | if (v == nullptr || !JSValueIsObject(jsctx, v)) { 96 | return NO; 97 | } 98 | } 99 | auto o = JSValueToObject(jsctx, v, nullptr); 100 | if (o == nullptr) { return NO; } 101 | auto rv = JSObjectCallAsFunction(jsctx, o, jsobj, 0, nullptr, nullptr); 102 | return rv != nullptr; 103 | } 104 | 105 | }; 106 | 107 | 108 | static JSNotification* _JSNotificationGet(JSContextRef ctx, JSObjectRef obj, JSValueRef* exc) { 109 | auto p = (JSNotification*)JSObjectGetPrivate(obj); 110 | if (p == nullptr && exc != nullptr) { 111 | *exc = JSClass::createJSError(ctx, u"method called on unexpected \"this\" object"); 112 | } 113 | return p; 114 | } 115 | 116 | 117 | BOOL JSNotificationDidActivate(JSContextRef ctx, JSObjectRef obj, NSUserNotification* notif) { 118 | auto p = _JSNotificationGet(ctx, obj, nullptr); 119 | if (p == nullptr) { return NO; } 120 | return p->didActivate(notif); 121 | } 122 | 123 | -------------------------------------------------------------------------------- /js-env-research/DbVL0yMlRcI.js: -------------------------------------------------------------------------------- 1 | if (self.CavalryLogger) { 2 | CavalryLogger.start_js([ "d7V4X" ]); 3 | } 4 | 5 | __d("DetectBrokenProxyCache", [ "AsyncSignal", "Cookie", "URI" ], function(a, b, c, d, e, f, g, h, i) { 6 | b.__markCompiled && b.__markCompiled(); 7 | function j(k, l) { 8 | var m = h.get(l); 9 | if (m != k && m != null && k != "0") { 10 | var n = { 11 | c: "si_detect_broken_proxy_cache", 12 | m: l + " " + k + " " + m 13 | }, o = new i("/common/scribe_endpoint.php").getQualifiedURI().toString(); 14 | new g(o, n).send(); 15 | } 16 | } 17 | e.exports = { 18 | run: j 19 | }; 20 | }, null); 21 | 22 | __d("DimensionLogging", [ "BanzaiNectar", "DOMDimensions" ], function(a, b, c, d, e, f, g, h) { 23 | b.__markCompiled && b.__markCompiled(); 24 | var i = h.getViewportDimensions(); 25 | g.log("browser_dimension", "homeload", { 26 | x: i.width, 27 | y: i.height, 28 | sw: window.screen.width, 29 | sh: window.screen.height, 30 | aw: window.screen.availWidth, 31 | ah: window.screen.availHeight, 32 | at: window.screen.availTop, 33 | al: window.screen.availLeft 34 | }); 35 | }, null); 36 | 37 | __d("DimensionTracking", [ "Cookie", "DOMDimensions", "Event", "debounce", "isInIframe" ], function(a, b, c, d, e, f, g, h, i, j, k) { 38 | b.__markCompiled && b.__markCompiled(); 39 | function l() { 40 | var m = h.getViewportDimensions(); 41 | g.set("wd", m.width + "x" + m.height); 42 | } 43 | if (!k()) { 44 | setTimeout(l, 100); 45 | i.listen(window, "resize", j(l, 250)); 46 | i.listen(window, "focus", l); 47 | } 48 | }, null); 49 | 50 | __d("HighContrastMode", [ "AccessibilityLogger", "CSS", "CurrentUser", "DOM", "Style", "emptyFunction" ], function(a, b, c, d, e, f, g, h, i, j, k, l) { 51 | b.__markCompiled && b.__markCompiled(); 52 | var m = { 53 | init: function(n) { 54 | if (window.top !== window.self) return; 55 | var o = j.create("div"); 56 | j.appendContent(document.body, o); 57 | o.style.cssText = "border: 1px solid;" + "border-color: red green;" + "position: fixed;" + "height: 5px;" + "top: -999px;" + "background-image: url(" + n.spacerImage + ");"; 58 | var p = k.get(o, "background-image"), q = k.get(o, "border-top-color"), r = k.get(o, "border-right-color"), s = q == r && (p && (p == "none" || p == "url(invalid-url:)")); 59 | if (s) { 60 | h.conditionClass(document.documentElement, "highContrast", s); 61 | if (i.getID()) g.logHCM(); 62 | } 63 | j.remove(o); 64 | m.init = l; 65 | } 66 | }; 67 | e.exports = m; 68 | }, null); 69 | 70 | __d("Live", [ "Arbiter", "AsyncDOM", "AsyncSignal", "ChannelConstants", "DataStore", "DOM", "ServerJS", "createArrayFromMixed", "emptyFunction" ], function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) { 71 | b.__markCompiled && b.__markCompiled(); 72 | function p(r, s) { 73 | s = JSON.parse(JSON.stringify(s)); 74 | new m().setRelativeTo(r).handle(s); 75 | } 76 | var q = { 77 | logAll: false, 78 | startup: function(r) { 79 | q.logAll = r; 80 | q.startup = o; 81 | g.subscribe(j.getArbiterType("live"), q.handleMessage.bind(q)); 82 | }, 83 | lookupLiveNode: function(r, s) { 84 | var t = l.scry(document.body, ".live_" + r + "_" + s); 85 | t.forEach(function(u) { 86 | if (k.get(u, "seqnum") === void 0) { 87 | var v = JSON.parse(u.getAttribute("data-live")); 88 | k.set(u, "seqnum", v.seq); 89 | } 90 | }); 91 | return t; 92 | }, 93 | handleMessage: function(r, s) { 94 | var t = s.obj, u = t.fbid, v = t.assoc, w = this.lookupLiveNode(u, v); 95 | if (!w) return false; 96 | w.forEach(function(x) { 97 | h.invoke(t.updates, x); 98 | if (t.js) p(x, t.js); 99 | }); 100 | }, 101 | log: function() { 102 | if (q.logAll) { 103 | var r = n(arguments).join(":"); 104 | new i("/common/scribe_endpoint.php", { 105 | c: "live_sequence", 106 | m: r 107 | }).send(); 108 | } 109 | } 110 | }; 111 | e.exports = q; 112 | }, null); 113 | 114 | __d("UFITracking", [ "Bootloader" ], function(a, b, c, d, e, f, g) { 115 | b.__markCompiled && b.__markCompiled(); 116 | function h(j) { 117 | g.loadModules([ "DOM", "collectDataAttributes" ], function(k, l) { 118 | j.forEach(function(m) { 119 | var n = k.scry(document.body, m); 120 | if (!n || n.link_data) return; 121 | var o = l(n, [ "ft" ]).ft; 122 | if (Object.keys(o).length) { 123 | var p = k.create("input", { 124 | type: "hidden", 125 | name: "link_data", 126 | value: JSON.stringify(o) 127 | }); 128 | n.appendChild(p); 129 | } 130 | }); 131 | }); 132 | } 133 | var i = { 134 | addAllLinkData: function() { 135 | h([ "form.commentable_item" ]); 136 | }, 137 | addAllLinkDataForQuestion: function() { 138 | h([ "form.fbEigenpollForm", "form.fbQuestionPollForm" ]); 139 | } 140 | }; 141 | e.exports = i; 142 | }, null); -------------------------------------------------------------------------------- /changelog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Messenger for Mac Changelog 5 | http://fbmacmessenger.rsms.me/changelog.xml 6 | Most recent changes with links to updates 7 | en 8 | 9 | Messenger for Mac 0.0.4 10 | 12 |
  • Enables zooming of the UI with ⌘-, ⌘+, and ⌘0)
  • 13 |
  • Enabled jumping to a conversation using ⌘1..9 where the number correlates to the "nth" list item
  • 14 |
  • Input focus is now given to the message composer when the window is activated
  • 15 |
  • Fixes a bug with Facebook two-factor authentication (no longer opens external web browser)
  • 16 |
  • Adds support for OS X 10.9
  • 17 |
  • Adds "unseen messages" badge to app icon that follows Messenger's badging logic
  • 18 |
  • Adds keyboard shortcut for search (⌘F)
  • 19 | 20 | ]]>
    21 | Thu, 09 Apr 2015 19:58:35 -0700 22 | 10.9 23 | 29 |
    30 | 31 | Messenger for Mac 0.0.3 32 | 34 |
  • Pretty error messages for when things go awry (no internet connection, messenger.com is down, etc)
  • 35 |
  • Adds support for attaching files
  • 36 |
  • Fixes a bug where Cmd-W wouldn't close the window
  • 37 |
  • Fixes a bug where opening links or downloading images would not open in the default web browser
  • 38 |
  • Saves the window position & size between app launches
  • 39 |
  • Adds fullscreen support
  • 40 | 41 | ]]>
    42 | Thu, 09 Apr 2015 00:44:29 -0700 43 | 10.10 44 | 50 |
    51 | 52 | Messenger for Mac 0.0.2 53 | 55 |
  • Show better maintenance message for 400 errors, when messenger.com is faulting
  • 56 |
  • Window controls (close, minimize, etc) now appears when the pointer is inside the window titlebar
  • 57 | 58 | ]]>
    59 | Wed, 08 Apr 2015 19:40:27 -0700 60 | 10.10 61 | 67 |
    68 | 69 | Messenger for Mac 0.0.2 70 | 72 |
  • Allows signing in to Facebook upon first launch
  • 73 |
  • Fixes a bug with the window where closing the main window would require an app restart to get it back on screen
  • 74 | 75 | ]]>
    76 | Wed, 08 Apr 2015 18:11:02 -0700 77 | 10.10 78 | 84 |
    85 | 86 | Messenger for Mac 0.0.2 87 | 89 |
  • Fixes a bug with local storage file system location
  • 90 | 91 | ]]>
    92 | Wed, 08 Apr 2015 17:59:51 -0700 93 | 10.10 94 | 100 |
    101 | 102 | Messenger for Mac 0.0.2 103 | 105 |
  • Adds desktop notifications, which can be enabled via the "gear" icon in the top-right corner of the main window
  • 106 | 107 | ]]>
    108 | Wed, 08 Apr 2015 17:57:07 -0700 109 | 10.10 110 | 116 |
    117 | 118 | Messenger for Mac 0.0.1 119 | 121 |
  • New icon (sdw)
  • 122 |
  • Clicking hyperlinks now open in default web browser (joshpuckett)
  • 123 | 124 | ]]>
    125 | Wed, 08 Apr 2015 14:19:39 -0700 126 | 10.10 127 | 133 |
    134 | 135 | Messenger for Mac 0.0.1 136 | 138 |
  • Initial release
  • 139 | 140 | ]]>
    141 | Wed, 08 Apr 2015 14:09:59 -0700 142 | 10.10 143 | 149 |
    150 |
    151 |
    152 | -------------------------------------------------------------------------------- /Messenger/JSClass.hh: -------------------------------------------------------------------------------- 1 | // 2 | // Inherit from this class to build JavaScript object "classes" preprocessed by jscls 3 | // 4 | #pragma once 5 | #import 6 | #import 7 | #import 8 | 9 | 10 | struct JSClass { 11 | 12 | // copies enumerable properties from object src to object dst as read-only properties 13 | static bool extendJSObject(JSContextRef ctx, JSObjectRef src, JSObjectRef dst, JSValueRef* exc); 14 | 15 | #pragma mark - Helpers 16 | 17 | using ArrayVisitor = bool(^)(unsigned int i, JSValueRef v, JSValueRef* exc); 18 | 19 | // Since JSValueToObject does not set an error when failing, this does 20 | static JSObjectRef JSValueToJSObject(JSContextRef ctx, JSValueRef value, JSValueRef* exc=nullptr); 21 | 22 | // Visit each entry in an array. Returns false and sets exc (unless nullptr) on failure. 23 | static bool walkArray(JSContextRef ctx, JSValueRef arrayValue, ArrayVisitor visitor, JSValueRef* exc=nullptr); 24 | 25 | static std::u16string U16StringFromJSValue(JSContextRef ctx, JSValueRef v, JSValueRef* exc=nullptr); 26 | static NSString* NSStringFromJSValue(JSContextRef ctx, JSValueRef v, JSValueRef* exc=nullptr); 27 | static JSValueRef JSValueFromNSString(JSContextRef ctx, NSString* s); 28 | static JSValueRef JSValueFromU16String(JSContextRef ctx, const std::u16string&); 29 | 30 | std::u16string U16StringFromJSValue(JSValueRef v, JSValueRef* exc=nullptr) { return U16StringFromJSValue(jsctx, v, exc); } 31 | NSString* NSStringFromJSValue(JSValueRef v, JSValueRef* exc=nullptr) { return NSStringFromJSValue(jsctx, v, exc); } 32 | JSValueRef JSValueFromNSString(NSString* s) { return JSValueFromNSString(jsctx, s); } 33 | 34 | // Create JSObject from map-like objects (std::map, std::unordered_map, etc) 35 | template ()->first)>::value 37 | && std::is_constructible()->second)>::value, 38 | int>::type = 0> 39 | JSObjectRef makeJSObject(JSPropertyAttributes attrs, A I, const B& end, JSValueRef* exc) { 40 | auto obj = JSObjectMake(jsctx, nullptr, nullptr); 41 | for (;I != end; I++) { 42 | auto name = JSStringCreateWithCharacters((const JSChar*)I->first.data(), I->first.size()); 43 | JSObjectSetProperty(jsctx, obj, name, I->second, attrs, exc); 44 | JSStringRelease(name); 45 | } 46 | return obj; 47 | } 48 | 49 | template ().begin()->first)>::value 51 | && std::is_constructible().begin()->second)>::value, 52 | int>::type = 0> 53 | JSObjectRef makeJSObject(JSPropertyAttributes attrs, const M& m, JSValueRef* exc) { 54 | return makeJSObject(attrs, m.begin(), m.end(), exc); 55 | } 56 | 57 | JSObjectRef makeJSObject(JSPropertyAttributes, const std::map&, JSValueRef* exc); 58 | 59 | #pragma mark - Properties 60 | 61 | static bool hasProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr); 62 | 63 | // Get property or throw exception if not found 64 | static JSValueRef getProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr); 65 | // Get property or returns undefined if not found 66 | static JSValueRef tryGetProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname); 67 | static JSValueRef tryGetProperty(JSContextRef ctx, JSObjectRef obj, const std::u16string& propname); 68 | JSValueRef tryGetProperty(const std::u16string& propname) { return JSClass::tryGetProperty(jsctx, jsobj, propname); } 69 | 70 | static JSObjectRef getObjectProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr); 71 | 72 | static std::u16string getU16StringProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr); 73 | static NSString* getNSStringProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr); 74 | 75 | JSValueRef getProperty(JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr) { 76 | return getProperty(jsctx, obj, propname, exc); 77 | } 78 | JSValueRef getProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc=nullptr); // deprecated 79 | JSValueRef getProperty(NSString* propname, JSValueRef* exc=nullptr) { 80 | return getProperty(jsobj, propname, exc); 81 | } 82 | 83 | JSObjectRef getObjectProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc=nullptr); // deprecated 84 | JSObjectRef getObjectProperty(NSString* propname, JSValueRef* exc=nullptr) { 85 | return getObjectProperty(jsobj, propname, exc); 86 | } 87 | 88 | std::u16string getU16StringProperty(JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr) { 89 | return getU16StringProperty(jsctx, obj, propname, exc); 90 | } 91 | std::u16string getU16StringProperty(const char16_t* propname, JSValueRef* exc=nullptr) { 92 | return getU16StringProperty(jsobj, propname, exc); 93 | } 94 | 95 | NSString* getNSStringProperty(JSObjectRef obj, const char16_t* propname, JSValueRef* exc=nullptr) { 96 | return getNSStringProperty(jsctx, obj, propname, exc); 97 | } 98 | NSString* getNSStringProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc=nullptr); // deprecated 99 | NSString* getNSStringProperty(NSString* propname, JSValueRef* exc=nullptr) { 100 | return getNSStringProperty(jsobj, propname, exc); 101 | } 102 | 103 | // Returns NaN if an exception was thrown 104 | static double getNumberProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, double defaultValue=0.0, JSValueRef* exc=nullptr); 105 | static double tryGetNumberProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, double defaultValue=0.0); 106 | 107 | double getNumberProperty(JSObjectRef obj, const char16_t* propname, double defaultValue=0.0, JSValueRef* exc=nullptr) { 108 | return getNumberProperty(jsctx, obj, propname, defaultValue, exc); 109 | } 110 | double getNumberProperty(JSObjectRef obj, NSString* propname, double defaultValue=0.0, JSValueRef* exc=nullptr); 111 | double getNumberProperty(NSString* propname, double defaultValue=0.0, JSValueRef* exc=nullptr) { 112 | return getNumberProperty(jsobj, propname, defaultValue, exc); 113 | } 114 | 115 | static bool setProperty(JSContextRef, JSObjectRef dst, const char16_t* propname, JSValueRef v, JSValueRef* exc=nullptr, JSPropertyAttributes attrs=kJSPropertyAttributeReadOnly); 116 | 117 | #pragma mark - Errors 118 | 119 | static JSObjectRef createJSError(JSContextRef ctx, NSString* message); 120 | static JSObjectRef createJSError(JSContextRef ctx, const std::u16string& message); 121 | static JSObjectRef createJSError(JSContextRef ctx, const std::string& message); 122 | static JSObjectRef createJSError(JSContextRef ctx, const char16_t* message); 123 | static JSObjectRef createJSError(JSContextRef ctx, JSStringRef message); 124 | 125 | #pragma mark - Internal 126 | 127 | // These values are only valid within jscall_*, jsget_* and jsset_* method calls. 128 | JSGlobalContextRef jsctx; 129 | JSObjectRef jsobj; 130 | }; 131 | -------------------------------------------------------------------------------- /js-env-research/y3PWxFZtgFE.js: -------------------------------------------------------------------------------- 1 | if (self.CavalryLogger) { 2 | CavalryLogger.start_js([ "plqFk" ]); 3 | } 4 | 5 | __d("getMarkupWrap", [ "ExecutionEnvironment", "invariant" ], function(a, b, c, d, e, f, g, h) { 6 | b.__markCompiled && b.__markCompiled(); 7 | var i = g.canUseDOM ? document.createElement("div") : null, j = { 8 | circle: true, 9 | defs: true, 10 | ellipse: true, 11 | g: true, 12 | line: true, 13 | linearGradient: true, 14 | path: true, 15 | polygon: true, 16 | polyline: true, 17 | radialGradient: true, 18 | rect: true, 19 | stop: true, 20 | text: true 21 | }, k = [ 1, '" ], l = [ 1, "", "
    " ], m = [ 3, "", "
    " ], n = [ 1, "", "" ], o = { 22 | "*": [ 1, "?
    ", "
    " ], 23 | area: [ 1, "", "" ], 24 | col: [ 2, "", "
    " ], 25 | legend: [ 1, "
    ", "
    " ], 26 | param: [ 1, "", "" ], 27 | tr: [ 2, "", "
    " ], 28 | optgroup: k, 29 | option: k, 30 | caption: l, 31 | colgroup: l, 32 | tbody: l, 33 | tfoot: l, 34 | thead: l, 35 | td: m, 36 | th: m, 37 | circle: n, 38 | defs: n, 39 | ellipse: n, 40 | g: n, 41 | line: n, 42 | linearGradient: n, 43 | path: n, 44 | polygon: n, 45 | polyline: n, 46 | radialGradient: n, 47 | rect: n, 48 | stop: n, 49 | text: n 50 | }; 51 | function p(q) { 52 | h(!!i); 53 | if (!o.hasOwnProperty(q)) q = "*"; 54 | if (!j.hasOwnProperty(q)) { 55 | if (q === "*") { 56 | i.innerHTML = ""; 57 | } else i.innerHTML = "<" + q + ">"; 58 | j[q] = !i.firstChild; 59 | } 60 | return j[q] ? o[q] : null; 61 | } 62 | e.exports = p; 63 | }, null); 64 | 65 | __d("createNodesFromMarkup", [ "ExecutionEnvironment", "createArrayFromMixed", "getMarkupWrap", "invariant" ], function(a, b, c, d, e, f, g, h, i, j) { 66 | b.__markCompiled && b.__markCompiled(); 67 | var k = g.canUseDOM ? document.createElement("div") : null, l = /^\s*<(\w+)/; 68 | function m(o) { 69 | var p = o.match(l); 70 | return p && p[1].toLowerCase(); 71 | } 72 | function n(o, p) { 73 | var q = k; 74 | j(!!k); 75 | var r = m(o), s = r && i(r); 76 | if (s) { 77 | q.innerHTML = s[1] + o + s[2]; 78 | var t = s[0]; 79 | while (t--) q = q.lastChild; 80 | } else q.innerHTML = o; 81 | var u = q.getElementsByTagName("script"); 82 | if (u.length) { 83 | j(p); 84 | h(u).forEach(p); 85 | } 86 | var v = h(q.childNodes); 87 | while (q.lastChild) q.removeChild(q.lastChild); 88 | return v; 89 | } 90 | e.exports = n; 91 | }, null); 92 | 93 | __d("evalGlobal", [], function(a, b, c, d, e, f) { 94 | b.__markCompiled && b.__markCompiled(); 95 | function g(h) { 96 | if (typeof h != "string") throw new TypeError("JS sent to evalGlobal is not a string. Only strings are permitted."); 97 | if (!h) return; 98 | var i = document.createElement("script"); 99 | try { 100 | i.appendChild(document.createTextNode(h)); 101 | } catch (j) { 102 | i.text = h; 103 | } 104 | var k = document.getElementsByTagName("head")[0] || document.documentElement; 105 | k.appendChild(i); 106 | k.removeChild(i); 107 | } 108 | e.exports = g; 109 | }, null); 110 | 111 | __d("FbtLoggerImpl", [ "BanzaiLogger" ], function(a, b, c, d, e, f, g) { 112 | b.__markCompiled && b.__markCompiled(); 113 | var h = { 114 | logImpression: function(i) { 115 | g.log("FbtImpressionsLoggerConfig", { 116 | hash: i, 117 | sample_rate: 100 118 | }); 119 | } 120 | }; 121 | e.exports = h; 122 | }, null); 123 | 124 | __d("HTML", [ "Bootloader", "createNodesFromMarkup", "emptyFunction", "evalGlobal", "invariant" ], function(a, b, c, d, e, f, g, h, i, j, k) { 125 | b.__markCompiled && b.__markCompiled(); 126 | var l = /(<(\w+)[^>]*?)\/>/g, m = { 127 | abbr: true, 128 | area: true, 129 | br: true, 130 | col: true, 131 | embed: true, 132 | hr: true, 133 | img: true, 134 | input: true, 135 | link: true, 136 | meta: true, 137 | param: true 138 | }; 139 | function n(o) { 140 | "use strict"; 141 | if (o && typeof o.__html === "string") o = o.__html; 142 | if (!(this instanceof n)) { 143 | if (o instanceof n) return o; 144 | return new n(o); 145 | } 146 | if (o) { 147 | var p = typeof o; 148 | k(p === "string"); 149 | } 150 | this._markup = o || ""; 151 | this._defer = false; 152 | this._extraAction = ""; 153 | this._nodes = null; 154 | this._inlineJS = i; 155 | this._rootNode = null; 156 | } 157 | n.prototype.toString = function() { 158 | "use strict"; 159 | var o = this._markup; 160 | if (this._extraAction) o += ' 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /js-env-research/FoHrp55D04d.js: -------------------------------------------------------------------------------- 1 | if (self.CavalryLogger) { 2 | CavalryLogger.start_js([ "ONkCB" ]); 3 | } 4 | 5 | __d("MessengerProfileImageWrapper.react", [ "ReactComponentWithPureRenderMixin", "React", "cx", "joinClasses" ], function(a, b, c, d, e, f, g, h, i, j) { 6 | b.__markCompiled && b.__markCompiled(); 7 | "use strict"; 8 | var k = h, l = k.PropTypes, m = h.createClass({ 9 | displayName: "MessengerProfileImageWrapper", 10 | mixins: [ g ], 11 | propTypes: { 12 | isMessengerUser: l.bool, 13 | showBadge: l.bool, 14 | size: l.number 15 | }, 16 | render: function() { 17 | return h.createElement("div", { 18 | className: j("_4ldz", this.props.className), 19 | style: { 20 | width: this.props.size + "px", 21 | height: this.props.size + "px" 22 | } 23 | }, h.createElement("div", { 24 | className: "_4ld-", 25 | style: { 26 | width: this.props.size + "px", 27 | height: this.props.size + "px" 28 | } 29 | }, this.props.children), this._renderBadge()); 30 | }, 31 | _renderBadge: function() { 32 | if (!this.props.showBadge || this.props.isMessengerUser == null) return null; 33 | return h.createElement(n, { 34 | className: "_4ld_", 35 | isMessengerUser: this.props.isMessengerUser 36 | }); 37 | } 38 | }), n = h.createClass({ 39 | displayName: "MessengerBadge", 40 | mixins: [ g ], 41 | propTypes: { 42 | isMessengerUser: l.bool, 43 | size: l.number 44 | }, 45 | render: function() { 46 | return h.createElement("div", { 47 | className: j(this.props.className, "_2pom") 48 | }, h.createElement("div", { 49 | className: "_2pon" + (this.props.isMessengerUser ? " " + "_2poo" : "") + (!this.props.isMessengerUser ? " " + "_2pop" : "") 50 | })); 51 | } 52 | }); 53 | e.exports = m; 54 | }, null); 55 | 56 | __d("MessengerContactImage.react", [ "Image.react", "MessengerProfileImageWrapper.react", "ReactComponentWithPureRenderMixin", "React" ], function(a, b, c, d, e, f, g, h, i, j) { 57 | b.__markCompiled && b.__markCompiled(); 58 | var k = j, l = k.PropTypes, m = j.createClass({ 59 | displayName: "MessengerContactImage", 60 | mixins: [ i ], 61 | propTypes: { 62 | isMessengerUser: l.bool, 63 | size: l.number.isRequired, 64 | src: l.string.isRequired 65 | }, 66 | render: function() { 67 | return j.createElement("div", { 68 | className: this.props.className 69 | }, j.createElement(h, { 70 | isMessengerUser: this.props.isMessengerUser, 71 | size: this.props.size, 72 | showBadge: true 73 | }, j.createElement(g, { 74 | height: this.props.size, 75 | src: this.props.src, 76 | width: this.props.size 77 | }))); 78 | } 79 | }); 80 | e.exports = m; 81 | }, null); 82 | 83 | __d("MessengerButton.react", [ "ReactComponentWithPureRenderMixin", "React", "cx", "joinClasses" ], function(a, b, c, d, e, f, g, h, i, j) { 84 | b.__markCompiled && b.__markCompiled(); 85 | "use strict"; 86 | var k = h, l = k.PropTypes, m = h.createClass({ 87 | displayName: "MessengerButton", 88 | mixins: [ g ], 89 | propTypes: { 90 | label: l.string.isRequired, 91 | type: l.oneOf([ "primary", "secondary" ]).isRequired, 92 | use: l.oneOf([ "default", "danger" ]).isRequired 93 | }, 94 | getDefaultProps: function() { 95 | return { 96 | use: "default" 97 | }; 98 | }, 99 | handleLinkClick: function(n) { 100 | if (this.props.disabled) { 101 | n.preventDefault(); 102 | } else if (this.props.onClick) this.props.onClick(n); 103 | }, 104 | render: function() { 105 | var n = this.props, o = n.className, p = n.label, q = function(r, s) { 106 | var t = {}, u = Object.prototype.hasOwnProperty; 107 | if (r == null) throw new TypeError(); 108 | for (var v in r) if (u.call(r, v) && !u.call(s, v)) t[v] = r[v]; 109 | return t; 110 | }(n, { 111 | className: 1, 112 | label: 1 113 | }); 114 | return h.createElement("a", h.__spread({ 115 | className: j("_3quh" + (" " + "_5vn4") + (" " + "_30yy") + (this.props.type === "primary" ? " " + "_3qui" : "") + (this.props.type === "secondary" ? " " + "_3quj" : "") + (this.props.use === "danger" ? " " + "_3ay_" : "") + (this.props.disabled ? " " + "_4zab" : ""), o), 116 | href: "#" 117 | }, q, { 118 | onClick: this.handleLinkClick 119 | }), p); 120 | } 121 | }); 122 | e.exports = m; 123 | }, null); 124 | 125 | __d("MessengerSpinner.react", [ "Image.react", "ReactComponentWithPureRenderMixin", "React", "cx", "fbt", "ix", "joinClasses" ], function(a, b, c, d, e, f, g, h, i, j, k, l, m) { 126 | b.__markCompiled && b.__markCompiled(); 127 | "use strict"; 128 | var n = i, o = n.PropTypes, p = l("/unpublished/images/messenger/core/LoadingSpinner.png"), q = l("/unpublished/images/messenger/core/LoadingSpinnerGrey.png"), r = 24, s = i.createClass({ 129 | displayName: "MessengerSpinner", 130 | mixins: [ h ], 131 | propTypes: { 132 | color: o.oneOf([ "blue", "grey" ]) 133 | }, 134 | getDefaultProps: function() { 135 | return { 136 | color: "blue" 137 | }; 138 | }, 139 | render: function() { 140 | return i.createElement(g, { 141 | "aria-label": k._("Loading..."), 142 | "aria-busy": true, 143 | className: m(this.props.className, "_3u55 _3qh2"), 144 | height: r, 145 | src: this.props.color === "blue" ? p : q, 146 | width: r 147 | }); 148 | } 149 | }); 150 | e.exports = s; 151 | }, null); 152 | 153 | __d("MNCommerceAttachmentConstants", [], function(a, b, c, d, e, f) { 154 | b.__markCompiled && b.__markCompiled(); 155 | var g = { 156 | XLARGE_IMAGE_DIMENSION: 72, 157 | LARGE_IMAGE_DIMENSION: 60, 158 | SMALL_IMAGE_DIMENSION: 32, 159 | BUBBLE_PADDING: 6, 160 | DIALOG: { 161 | WIDTH: 445, 162 | PADDING: 12 163 | }, 164 | ORDER_DETAIL: { 165 | SUB_TOTAL: "subTotal", 166 | SHIPPING: "shippingCost", 167 | TAX: "tax", 168 | TOTAL: "totalCost" 169 | } 170 | }; 171 | e.exports = g; 172 | }, null); 173 | 174 | __d("isRetina", [], function(a, b, c, d, e, f) { 175 | b.__markCompiled && b.__markCompiled(); 176 | "use strict"; 177 | e.exports = function() { 178 | return (window.devicePixelRatio || 1) > 1; 179 | }; 180 | }, null); 181 | 182 | __d("MessengerPage", [ "EventEmitter", "EventEmitterWithHolding", "EventHolder", "keyMirror", "performanceAbsoluteNow" ], function(a, b, c, d, e, f, g, h, i, j, k) { 183 | b.__markCompiled && b.__markCompiled(); 184 | "use strict"; 185 | var l = { 186 | Events: j({ 187 | APP_MOUNTED: null, 188 | DATA_INITIALIZED: null, 189 | JS_LOADED: null 190 | }), 191 | addRetroactiveListener: function(n, o) { 192 | return m.addRetroactiveListener(n, o); 193 | }, 194 | emit: function(n) { 195 | m.emitAndHold(n, k()); 196 | }, 197 | removeCurrentListener: function() { 198 | m.removeCurrentListener(); 199 | } 200 | }, m = new h(new g(), new i()); 201 | e.exports = l; 202 | }, null); 203 | 204 | __d("MessengerArtilleryClient", [ "Artillery", "ArtilleryCategory", "ArtillerySequenceType", "Banzai", "MessengerPage", "NavigationConfiguration", "Promise", "TimingSegmentBuilder", "performance" ], function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) { 205 | b.__markCompiled && b.__markCompiled(); 206 | "use strict"; 207 | var p = { 208 | start: function() { 209 | if (!g.isEnabled() || !o.timing || !window._cstart) return; 210 | var t = g.getPageTrace(); 211 | q(t); 212 | r(k.Events.JS_LOADED, k.Events.DATA_INITIALIZED, k.Events.APP_MOUNTED).then(function(u) { 213 | var v = u[0], w = u[1], x = u[2], y = t.createSegment({ 214 | category: h.CLIENT, 215 | description: "requiring_modules", 216 | begin: window._cstart, 217 | end: v 218 | }), z = t.createSegment({ 219 | category: h.CLIENT, 220 | description: "initializing_data", 221 | begin: v, 222 | end: w 223 | }), aa = t.createSegment({ 224 | category: h.CLIENT, 225 | description: "mounting_app", 226 | begin: w, 227 | end: x 228 | }), ba = t.createSequence({ 229 | description: "initialization", 230 | category: i.SEQUENCE_CLIENT 231 | }); 232 | ba.addSegment(y, z, aa); 233 | t.markSegment(aa, "e2e"); 234 | t.post(); 235 | }); 236 | j.subscribe(j.SHUTDOWN, function() { 237 | return g.postAll(); 238 | }); 239 | } 240 | }; 241 | function q(t) { 242 | var u = n.build(t, o.timing, l), v = t.createSequence({ 243 | description: "browser_navigation", 244 | category: i.SEQUENCE_CLIENT 245 | }); 246 | u.list.forEach(function(w) { 247 | return v.addSegment(w); 248 | }); 249 | } 250 | function r() { 251 | for (var t = [], u = 0, v = arguments.length; u < v; u++) t.push(arguments[u]); 252 | return m.all(t.map(s)); 253 | } 254 | function s(t) { 255 | return new m(function(u) { 256 | k.addRetroactiveListener(t, function(v) { 257 | k.removeCurrentListener(); 258 | u(v); 259 | }); 260 | }); 261 | } 262 | e.exports = p; 263 | }, null); 264 | 265 | __d("MessengerComposerSteps", [ "keyMirror" ], function(a, b, c, d, e, f, g) { 266 | b.__markCompiled && b.__markCompiled(); 267 | "use strict"; 268 | var h = g({ 269 | NULL: null, 270 | SELECT_RECIPIENTS: null, 271 | COMPOSE: null 272 | }); 273 | e.exports = h; 274 | }, null); -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ADP2,1 6 | Developer Transition Kit 7 | iMac1,1 8 | iMac G3 (Rev A-D) 9 | iMac4,1 10 | iMac (Core Duo) 11 | iMac4,2 12 | iMac for Education (17 inch, Core Duo) 13 | iMac5,1 14 | iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) 15 | iMac5,2 16 | iMac (Core 2 Duo, 17 inch, Combo Drive) 17 | iMac6,1 18 | iMac (Core 2 Duo, 24 inch, SuperDrive) 19 | iMac8,1 20 | iMac (Core 2 Duo, 20 or 24 inch, Early 2008 ) 21 | iMac9,1 22 | iMac (Core 2 Duo, 20 or 24 inch, Early or Mid 2009 ) 23 | iMac10,1 24 | iMac (Core 2 Duo, 21.5 or 27 inch, Late 2009 ) 25 | iMac11,1 26 | iMac (Core i5 or i7, 27 inch Late 2009) 27 | iMac11,2 28 | iMac (Core i3 or i5, 27 inch Mid 2010) 29 | iMac11,3 30 | iMac (Core i5 or i7, 27 inch Mid 2010) 31 | iMac12,1 32 | iMac (Core i3 or i5 or i7, 21.5 inch Mid 2010 or Late 2011) 33 | iMac12,2 34 | iMac (Core i5 or i7, 27 inch Mid 2011) 35 | iMac13,1 36 | iMac (Core i3 or i5 or i7, 21.5 inch Late 2012 or Early 2013) 37 | iMac13,2 38 | iMac (Core i5 or i7, 27 inch Late 2012) 39 | iMac14,1 40 | iMac (Core i5, 21.5 inch Late 2013) 41 | iMac14,2 42 | iMac (Core i5 or i7, 27 inch Late 2013) 43 | iMac14,3 44 | iMac (Core i5 or i7, 21.5 inch Late 2013) 45 | MacBook1,1 46 | MacBook (Core Duo) 47 | MacBook2,1 48 | MacBook (Core 2 Duo) 49 | MacBook4,1 50 | MacBook (Core 2 Duo Feb 2008) 51 | MacBook5,1 52 | MacBook (Core 2 Duo, Late 2008, Unibody) 53 | MacBook5,2 54 | MacBook (Core 2 Duo, Early 2009, White) 55 | MacBook6,1 56 | MacBook (Core 2 Duo, Late 2009, Unibody) 57 | MacBook7,1 58 | MacBook (Core 2 Duo, Mid 2010, White) 59 | MacBookAir1,1 60 | MacBook Air (Core 2 Duo, 13 inch, Early 2008) 61 | MacBookAir2,1 62 | MacBook Air (Core 2 Duo, 13 inch, Mid 2009) 63 | MacBookAir3,1 64 | MacBook Air (Core 2 Duo, 11 inch, Late 2010) 65 | MacBookAir3,2 66 | MacBook Air (Core 2 Duo, 13 inch, Late 2010) 67 | MacBookAir4,1 68 | MacBook Air (Core i5 or i7, 11 inch, Mid 2011) 69 | MacBookAir4,2 70 | MacBook Air (Core i5 or i7, 13 inch, Mid 2011) 71 | MacBookAir5,1 72 | MacBook Air (Core i5 or i7, 11 inch, Mid 2012) 73 | MacBookAir5,2 74 | MacBook Air (Core i5 or i7, 13 inch, Mid 2012) 75 | MacBookAir6,1 76 | MacBook Air (Core i5 or i7, 11 inch, Mid 2013 or Early 2014) 77 | MacBookAir6,2 78 | MacBook Air (Core i5 or i7, 13 inch, Mid 2013 or Early 2014) 79 | MacBookPro1,1 80 | MacBook Pro Core Duo (15-inch) 81 | MacBookPro1,2 82 | MacBook Pro Core Duo (17-inch) 83 | MacBookPro2,1 84 | MacBook Pro Core 2 Duo (17-inch) 85 | MacBookPro2,2 86 | MacBook Pro Core 2 Duo (15-inch) 87 | MacBookPro3,1 88 | MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) 89 | MacBookPro3,2 90 | MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) 91 | MacBookPro4,1 92 | MacBook Pro (Core 2 Duo Feb 2008) 93 | Macmini1,1 94 | Mac Mini (Core Solo/Duo) 95 | MacPro1,1 96 | Mac Pro (four-core) 97 | MacPro2,1 98 | Mac Pro (eight-core) 99 | MacPro3,1 100 | Mac Pro (January 2008 4- or 8- core "Harpertown") 101 | MacPro4,1 102 | Mac Pro (March 2009) 103 | MacPro5,1 104 | Mac Pro (August 2010) 105 | PowerBook1,1 106 | PowerBook G3 107 | PowerBook2,1 108 | iBook G3 109 | PowerBook2,2 110 | iBook G3 (FireWire) 111 | PowerBook2,3 112 | iBook G3 113 | PowerBook2,4 114 | iBook G3 115 | PowerBook3,1 116 | PowerBook G3 (FireWire) 117 | PowerBook3,2 118 | PowerBook G4 119 | PowerBook3,3 120 | PowerBook G4 (Gigabit Ethernet) 121 | PowerBook3,4 122 | PowerBook G4 (DVI) 123 | PowerBook3,5 124 | PowerBook G4 (1GHz / 867MHz) 125 | PowerBook4,1 126 | iBook G3 (Dual USB, Late 2001) 127 | PowerBook4,2 128 | iBook G3 (16MB VRAM) 129 | PowerBook4,3 130 | iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) 131 | PowerBook5,1 132 | PowerBook G4 (17 inch) 133 | PowerBook5,2 134 | PowerBook G4 (15 inch FW 800) 135 | PowerBook5,3 136 | PowerBook G4 (17-inch 1.33GHz) 137 | PowerBook5,4 138 | PowerBook G4 (15 inch 1.5/1.33GHz) 139 | PowerBook5,5 140 | PowerBook G4 (17-inch 1.5GHz) 141 | PowerBook5,6 142 | PowerBook G4 (15 inch 1.67GHz/1.5GHz) 143 | PowerBook5,7 144 | PowerBook G4 (17-inch 1.67GHz) 145 | PowerBook5,8 146 | PowerBook G4 (Double layer SD, 15 inch) 147 | PowerBook5,9 148 | PowerBook G4 (Double layer SD, 17 inch) 149 | PowerBook6,1 150 | PowerBook G4 (12 inch) 151 | PowerBook6,2 152 | PowerBook G4 (12 inch, DVI) 153 | PowerBook6,3 154 | iBook G4 155 | PowerBook6,4 156 | PowerBook G4 (12 inch 1.33GHz) 157 | PowerBook6,5 158 | iBook G4 (Early-Late 2004) 159 | PowerBook6,7 160 | iBook G4 (Mid 2005) 161 | PowerBook6,8 162 | PowerBook G4 (12 inch 1.5GHz) 163 | PowerMac1,1 164 | Power Macintosh G3 (Blue & White) 165 | PowerMac1,2 166 | Power Macintosh G4 (PCI Graphics) 167 | PowerMac10,1 168 | Mac Mini G4 169 | PowerMac10,2 170 | Mac Mini (Late 2005) 171 | PowerMac11,2 172 | Power Macintosh G5 (Late 2005) 173 | PowerMac12,1 174 | iMac G5 (iSight) 175 | PowerMac2,1 176 | iMac G3 (Slot-loading CD-ROM) 177 | PowerMac2,2 178 | iMac G3 (Summer 2000) 179 | PowerMac3,1 180 | Power Macintosh G4 (AGP Graphics) 181 | PowerMac3,2 182 | Power Macintosh G4 (AGP Graphics) 183 | PowerMac3,3 184 | Power Macintosh G4 (Gigabit Ethernet) 185 | PowerMac3,4 186 | Power Macintosh G4 (Digital Audio) 187 | PowerMac3,5 188 | Power Macintosh G4 (Quick Silver) 189 | PowerMac3,6 190 | Power Macintosh G4 (Mirrored Drive Door) 191 | PowerMac4,1 192 | iMac G3 (Early/Summer 2001) 193 | PowerMac4,2 194 | iMac G4 (Flat Panel) 195 | PowerMac4,4 196 | eMac 197 | PowerMac4,5 198 | iMac G4 (17-inch Flat Panel) 199 | PowerMac5,1 200 | Power Macintosh G4 Cube 201 | PowerMac6,1 202 | iMac G4 (USB 2.0) 203 | PowerMac6,3 204 | iMac G4 (20-inch Flat Panel) 205 | PowerMac6,4 206 | eMac (USB 2.0, 2005) 207 | PowerMac7,2 208 | Power Macintosh G5 209 | PowerMac7,3 210 | Power Macintosh G5 211 | PowerMac8,1 212 | iMac G5 213 | PowerMac8,2 214 | iMac G5 (Ambient Light Sensor) 215 | PowerMac9,1 216 | Power Macintosh G5 (Late 2005) 217 | RackMac1,1 218 | Xserve G4 219 | RackMac1,2 220 | Xserve G4 (slot-loading, cluster node) 221 | RackMac3,1 222 | Xserve G5 223 | Xserve1,1 224 | Xserve (Intel Xeon) 225 | Xserve2,1 226 | Xserve (January 2008 quad-core) 227 | 228 | 229 | -------------------------------------------------------------------------------- /Messenger/JSClass.mm: -------------------------------------------------------------------------------- 1 | #import "JSClass.hh" 2 | 3 | 4 | static JSStringRef kJSString_length; 5 | 6 | static void __attribute__((constructor))_init() { 7 | auto p = u"length"; 8 | kJSString_length = JSStringCreateWithCharacters((const JSChar*)p, std::char_traits::length(p)); 9 | } 10 | 11 | 12 | // copies enumerable properties from object src to object dst as read-only properties 13 | bool JSClass::extendJSObject(JSContextRef ctx, JSObjectRef src, JSObjectRef dst, JSValueRef* exc) { 14 | auto propv = JSObjectCopyPropertyNames(ctx, src); 15 | auto propc = JSPropertyNameArrayGetCount(propv); 16 | for (size_t i = 0; i != propc; ++i) { 17 | auto propName = JSPropertyNameArrayGetNameAtIndex(propv, i); 18 | auto propValue = JSObjectGetProperty(ctx, src, propName, exc); 19 | if (propValue == nullptr) { 20 | JSPropertyNameArrayRelease(propv); 21 | return false; 22 | } 23 | JSObjectSetProperty(ctx, dst, propName, propValue, kJSPropertyAttributeReadOnly, exc); 24 | if (exc != nullptr && *exc != nullptr) { 25 | return false; 26 | } 27 | } 28 | JSPropertyNameArrayRelease(propv); 29 | return true; 30 | } 31 | 32 | #pragma mark - Helpers 33 | 34 | JSObjectRef JSClass::JSValueToJSObject(JSContextRef ctx, JSValueRef v, JSValueRef* exc) { 35 | auto o = JSValueToObject(ctx, v, exc); 36 | if (o == nullptr) { 37 | if (exc != nullptr) *exc = createJSError(ctx, u"value is not an object"); 38 | } 39 | return o; 40 | } 41 | 42 | // Visit each entry in an array. Returns false and sets exc (unless nullptr) on failure. 43 | bool JSClass::walkArray(JSContextRef ctx, JSValueRef arrayValue, ArrayVisitor visitor, JSValueRef* exc) { 44 | //if (!JSValueIsObject(jsctx, arrayValue)) return false; 45 | auto o = JSValueToJSObject(ctx, arrayValue, exc); 46 | if (o == nullptr) return false; 47 | 48 | auto lengthv = JSObjectGetProperty(ctx, o, kJSString_length, exc); 49 | if (lengthv == nullptr) return false; 50 | 51 | auto length = (unsigned int)JSValueToNumber(ctx, lengthv, exc); 52 | for (unsigned int i = 0; i != length; ++i) { 53 | JSValueRef entryv = JSObjectGetPropertyAtIndex(ctx, o, i, exc); 54 | if (entryv == nullptr) return false; 55 | if (!visitor(i, entryv, exc)) return false; 56 | } 57 | 58 | return true; 59 | } 60 | 61 | std::u16string JSClass::U16StringFromJSValue(JSContextRef ctx, JSValueRef v, JSValueRef* exc) { 62 | if (!JSValueIsUndefined(ctx, v) && !JSValueIsNull(ctx, v)) { 63 | auto s = JSValueToStringCopy(ctx, v, exc); 64 | if (s != nullptr) { 65 | std::u16string u16str{(const char16_t*)JSStringGetCharactersPtr(s), JSStringGetLength(s)}; 66 | JSStringRelease(s); 67 | return u16str; 68 | } 69 | } 70 | return std::u16string{}; 71 | } 72 | 73 | NSString* JSClass::NSStringFromJSValue(JSContextRef ctx, JSValueRef v, JSValueRef* exc) { 74 | if (JSValueIsUndefined(ctx, v) || JSValueIsNull(ctx, v)) { 75 | return nil; 76 | } 77 | auto s = JSValueToStringCopy(ctx, v, exc); 78 | if (s != nullptr) { 79 | NSString* nsstr = (NSString*)CFBridgingRelease(JSStringCopyCFString(kCFAllocatorDefault, s)); 80 | JSStringRelease(s); 81 | return nsstr; 82 | } 83 | return nil; 84 | } 85 | 86 | JSValueRef JSClass::JSValueFromNSString(JSContextRef ctx, NSString* nsstr) { 87 | if (nsstr == nil) { 88 | return JSValueMakeNull(ctx); 89 | } 90 | auto s = JSStringCreateWithCFString((__bridge CFStringRef)nsstr); 91 | auto v = JSValueMakeString(ctx, s); 92 | JSStringRelease(s); 93 | return v; 94 | } 95 | 96 | JSValueRef JSClass::JSValueFromU16String(JSContextRef ctx, const std::u16string& str) { 97 | auto s = JSStringCreateWithCharacters((const JSChar*)str.data(), str.size()); 98 | auto v = JSValueMakeString(ctx, s); 99 | JSStringRelease(s); 100 | return v; 101 | } 102 | 103 | JSObjectRef JSClass::makeJSObject(JSPropertyAttributes attrs, 104 | const std::map& m, JSValueRef* exc) 105 | { 106 | return makeJSObject(attrs, m.begin(), m.end(), exc); 107 | } 108 | 109 | 110 | 111 | #pragma mark - Properties 112 | 113 | 114 | bool JSClass::hasProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* n, JSValueRef* exc) { 115 | auto s = JSStringCreateWithCharacters((const JSChar*)n, std::char_traits::length(n)); 116 | auto b = JSObjectHasProperty(ctx, obj, s); 117 | JSStringRelease(s); 118 | return b; 119 | } 120 | 121 | 122 | JSValueRef JSClass::getProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* n, JSValueRef* exc) { 123 | auto s = JSStringCreateWithCharacters((const JSChar*)n, std::char_traits::length(n)); 124 | auto v = JSObjectGetProperty(ctx, obj, s, exc); 125 | JSStringRelease(s); 126 | if (v == nullptr || JSValueIsUndefined(ctx, v)) { 127 | if (exc != nullptr) *exc = createJSError(ctx, std::u16string{u"property not found: \""} + n + u"\""); 128 | } 129 | return v; 130 | } 131 | 132 | JSValueRef JSClass::tryGetProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* n) { 133 | auto s = JSStringCreateWithCharacters((const JSChar*)n, std::char_traits::length(n)); 134 | auto v = JSObjectGetProperty(ctx, obj, s, nullptr); 135 | JSStringRelease(s); 136 | return v; 137 | } 138 | 139 | 140 | JSValueRef JSClass::tryGetProperty(JSContextRef ctx, JSObjectRef obj, const std::u16string& n) { 141 | auto s = JSStringCreateWithCharacters((const JSChar*)n.data(), n.size()); 142 | auto v = JSObjectGetProperty(ctx, obj, s, nullptr); 143 | JSStringRelease(s); 144 | return v; 145 | } 146 | 147 | 148 | JSObjectRef JSClass::getObjectProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc) { 149 | auto v = getProperty(ctx, obj, propname, exc); 150 | return v != nullptr ? JSValueToJSObject(ctx, v, exc) : nil; 151 | } 152 | 153 | 154 | std::u16string JSClass::getU16StringProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc) { 155 | auto v = getProperty(ctx, obj, propname, exc); 156 | return v != nullptr ? U16StringFromJSValue(ctx, v, exc) : std::u16string{}; 157 | } 158 | 159 | NSString* JSClass::getNSStringProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, JSValueRef* exc) { 160 | auto v = getProperty(ctx, obj, propname, exc); 161 | return v != nullptr ? NSStringFromJSValue(ctx, v, exc) : nil; 162 | } 163 | 164 | 165 | 166 | JSValueRef JSClass::getProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc) { 167 | auto s = JSStringCreateWithCFString((__bridge CFStringRef)propname); 168 | auto v = JSObjectGetProperty(jsctx, obj, s, exc); 169 | JSStringRelease(s); 170 | return v; 171 | } 172 | 173 | JSObjectRef JSClass::getObjectProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc) { 174 | auto v = getProperty(obj, propname, exc); 175 | return v != nullptr ? JSValueToJSObject(jsctx, v, exc) : nil; 176 | } 177 | 178 | NSString* JSClass::getNSStringProperty(JSObjectRef obj, NSString* propname, JSValueRef* exc) { 179 | auto v = getProperty(obj, propname, exc); 180 | return v != nullptr ? NSStringFromJSValue(v, exc) : nil; 181 | } 182 | 183 | double JSClass::getNumberProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, double defaultValue, JSValueRef* exc) { 184 | auto v = getProperty(ctx, obj, propname, exc); 185 | if (JSValueIsNumber(ctx, v)) { 186 | return JSValueToNumber(ctx, v, exc); 187 | } 188 | return defaultValue; 189 | } 190 | 191 | double JSClass::tryGetNumberProperty(JSContextRef ctx, JSObjectRef obj, const char16_t* propname, double defaultValue) { 192 | auto v = tryGetProperty(ctx, obj, propname); 193 | if (JSValueIsNumber(ctx, v)) { 194 | auto n = JSValueToNumber(ctx, v, nullptr); 195 | if (!isnan(n)) { 196 | return n; 197 | } 198 | } 199 | return defaultValue; 200 | } 201 | 202 | double JSClass::getNumberProperty(JSObjectRef obj, NSString* propname, double defaultValue, JSValueRef* exc) { 203 | auto v = getProperty(obj, propname, exc); 204 | if (v != nullptr && JSValueIsNumber(jsctx, v)) { 205 | return JSValueToNumber(jsctx, v, exc); 206 | } 207 | return defaultValue; 208 | } 209 | 210 | 211 | bool JSClass::setProperty(JSContextRef ctx, JSObjectRef dst, const char16_t* n, JSValueRef v, JSValueRef* exc, JSPropertyAttributes attrs) { 212 | auto propname = JSStringCreateWithCharacters((const JSChar*)n, std::char_traits::length(n)); 213 | JSObjectSetProperty(ctx, dst, propname, v, attrs, exc); 214 | JSStringRelease(propname); 215 | return (exc == nullptr || *exc == nullptr); 216 | } 217 | 218 | 219 | #pragma mark - Errors 220 | 221 | JSObjectRef JSClass::createJSError(JSContextRef ctx, NSString* message) { 222 | auto s = JSStringCreateWithCFString((__bridge CFStringRef)message); 223 | auto err = createJSError(ctx, s); 224 | JSStringRelease(s); 225 | return err; 226 | } 227 | 228 | JSObjectRef JSClass::createJSError(JSContextRef ctx, const std::string& message) { 229 | auto s = JSStringCreateWithUTF8CString(message.c_str()); 230 | auto err = createJSError(ctx, s); 231 | JSStringRelease(s); 232 | return err; 233 | } 234 | 235 | JSObjectRef JSClass::createJSError(JSContextRef ctx, const char16_t* message) { 236 | auto s = JSStringCreateWithCharacters( 237 | (const JSChar*)message, 238 | std::char_traits::length(message) 239 | ); 240 | auto err = createJSError(ctx, s); 241 | JSStringRelease(s); 242 | return err; 243 | } 244 | 245 | JSObjectRef JSClass::createJSError(JSContextRef ctx, const std::u16string& message) { 246 | auto s = JSStringCreateWithCharacters((const JSChar*)message.data(), message.size()); 247 | auto err = createJSError(ctx, s); 248 | JSStringRelease(s); 249 | return err; 250 | } 251 | 252 | JSObjectRef JSClass::createJSError(JSContextRef ctx, JSStringRef message) { 253 | auto v = JSValueMakeString(ctx, message); 254 | auto err = JSObjectMakeError(ctx, 1, &v, nullptr); 255 | assert(err != nullptr); // should only fail when out of memory, which shouldn't really happen 256 | return err; 257 | } 258 | 259 | 260 | -------------------------------------------------------------------------------- /sparkle/Sparkle.framework/Versions/A/Headers/SUUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdater.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/4/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATER_H 10 | #define SUUPDATER_H 11 | 12 | #import "SUVersionComparisonProtocol.h" 13 | #import "SUVersionDisplayProtocol.h" 14 | 15 | @class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; 16 | 17 | @protocol SUUpdaterDelegate; 18 | 19 | /*! 20 | The main API in Sparkle for controlling the update mechanism. 21 | 22 | This class is used to configure the update paramters as well as manually 23 | and automatically schedule and control checks for updates. 24 | */ 25 | @interface SUUpdater : NSObject 26 | 27 | @property (weak) IBOutlet id delegate; 28 | 29 | + (SUUpdater *)sharedUpdater; 30 | + (SUUpdater *)updaterForBundle:(NSBundle *)bundle; 31 | - (instancetype)initForBundle:(NSBundle *)bundle; 32 | 33 | @property (readonly, strong) NSBundle *hostBundle; 34 | 35 | @property BOOL automaticallyChecksForUpdates; 36 | 37 | @property NSTimeInterval updateCheckInterval; 38 | 39 | /*! 40 | * The URL of the appcast used to download update information. 41 | * 42 | * This property must be called on the main thread. 43 | */ 44 | @property (copy) NSURL *feedURL; 45 | 46 | @property (nonatomic, copy) NSString *userAgentString; 47 | 48 | @property BOOL sendsSystemProfile; 49 | 50 | @property BOOL automaticallyDownloadsUpdates; 51 | 52 | /*! 53 | Explicitly checks for updates and displays a progress dialog while doing so. 54 | 55 | This method is meant for a main menu item. 56 | Connect any menu item to this action in Interface Builder, 57 | and Sparkle will check for updates and report back its findings verbosely 58 | when it is invoked. 59 | */ 60 | - (IBAction)checkForUpdates:(id)sender; 61 | 62 | /*! 63 | Checks for updates, but does not display any UI unless an update is found. 64 | 65 | This is meant for programmatically initating a check for updates. That is, 66 | it will display no UI unless it actually finds an update, in which case it 67 | proceeds as usual. 68 | 69 | If the fully automated updating is turned on, however, this will invoke that 70 | behavior, and if an update is found, it will be downloaded and prepped for 71 | installation. 72 | */ 73 | - (void)checkForUpdatesInBackground; 74 | 75 | /*! 76 | Returns the date of last update check. 77 | 78 | \returns \c nil if no check has been performed. 79 | */ 80 | @property (readonly, copy) NSDate *lastUpdateCheckDate; 81 | 82 | /*! 83 | Begins a "probing" check for updates which will not actually offer to 84 | update to that version. 85 | 86 | However, the delegate methods 87 | SUUpdaterDelegate::updater:didFindValidUpdate: and 88 | SUUpdaterDelegate::updaterDidNotFindUpdate: will be called, 89 | so you can use that information in your UI. 90 | */ 91 | - (void)checkForUpdateInformation; 92 | 93 | /*! 94 | Appropriately schedules or cancels the update checking timer according to 95 | the preferences for time interval and automatic checks. 96 | 97 | This call does not change the date of the next check, 98 | but only the internal NSTimer. 99 | */ 100 | - (void)resetUpdateCycle; 101 | 102 | @property (readonly) BOOL updateInProgress; 103 | 104 | @end 105 | 106 | // ----------------------------------------------------------------------------- 107 | // SUUpdater Notifications for events that might be interesting to more than just the delegate 108 | // The updater will be the notification object 109 | // ----------------------------------------------------------------------------- 110 | extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification; 111 | extern NSString *const SUUpdaterDidFindValidUpdateNotification; 112 | extern NSString *const SUUpdaterDidNotFindUpdateNotification; 113 | extern NSString *const SUUpdaterWillRestartNotification; 114 | #define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification; 115 | #define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification; 116 | 117 | // Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo 118 | extern NSString *const SUUpdaterAppcastItemNotificationKey; 119 | // Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo 120 | extern NSString *const SUUpdaterAppcastNotificationKey; 121 | 122 | // ----------------------------------------------------------------------------- 123 | // SUUpdater Delegate: 124 | // ----------------------------------------------------------------------------- 125 | 126 | /*! 127 | Provides methods to control the behavior of an SUUpdater object. 128 | */ 129 | @protocol SUUpdaterDelegate 130 | @optional 131 | 132 | /*! 133 | Returns whether to allow Sparkle to pop up. 134 | 135 | For example, this may be used to prevent Sparkle from interrupting a setup assistant. 136 | 137 | \param updater The SUUpdater instance. 138 | */ 139 | - (BOOL)updaterMayCheckForUpdates:(SUUpdater *)updater; 140 | 141 | /*! 142 | Returns additional parameters to append to the appcast URL's query string. 143 | 144 | This is potentially based on whether or not Sparkle will also be sending along the system profile. 145 | 146 | \param updater The SUUpdater instance. 147 | \param sendingProfile Whether the system profile will also be sent. 148 | 149 | \return An array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. 150 | */ 151 | - (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; 152 | 153 | /*! 154 | Returns a custom appcast URL. 155 | 156 | Override this to dynamically specify the entire URL. 157 | 158 | \param updater The SUUpdater instance. 159 | */ 160 | - (NSString *)feedURLStringForUpdater:(SUUpdater *)updater; 161 | 162 | /*! 163 | Returns whether Sparkle should prompt the user about automatic update checks. 164 | 165 | Use this to override the default behavior. 166 | 167 | \param updater The SUUpdater instance. 168 | */ 169 | - (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)updater; 170 | 171 | /*! 172 | Called after Sparkle has downloaded the appcast from the remote server. 173 | 174 | Implement this if you want to do some special handling with the appcast once it finishes loading. 175 | 176 | \param updater The SUUpdater instance. 177 | \param appcast The appcast that was downloaded from the remote server. 178 | */ 179 | - (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; 180 | 181 | /*! 182 | Returns the item in the appcast corresponding to the update that should be installed. 183 | 184 | If you're using special logic or extensions in your appcast, 185 | implement this to use your own logic for finding a valid update, if any, 186 | in the given appcast. 187 | 188 | \param appcast The appcast that was downloaded from the remote server. 189 | \param updater The SUUpdater instance. 190 | */ 191 | - (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater; 192 | 193 | /*! 194 | Called when a valid update is found by the update driver. 195 | 196 | \param updater The SUUpdater instance. 197 | \param item The appcast item corresponding to the update that is proposed to be installed. 198 | */ 199 | - (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item; 200 | 201 | /*! 202 | Called when a valid update is not found. 203 | 204 | \param updater The SUUpdater instance. 205 | */ 206 | - (void)updaterDidNotFindUpdate:(SUUpdater *)updater; 207 | 208 | /*! 209 | Called immediately before installing the specified update. 210 | 211 | \param updater The SUUpdater instance. 212 | \param item The appcast item corresponding to the update that is proposed to be installed. 213 | */ 214 | - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item; 215 | 216 | /*! 217 | Returns whether the relaunch should be delayed in order to perform other tasks. 218 | 219 | This is not called if the user didn't relaunch on the previous update, 220 | in that case it will immediately restart. 221 | 222 | \param updater The SUUpdater instance. 223 | \param item The appcast item corresponding to the update that is proposed to be installed. 224 | \param invocation The invocation that must be completed before continuing with the relaunch. 225 | 226 | \return \c YES to delay the relaunch until \p invocation is invoked. 227 | */ 228 | - (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvoking:(NSInvocation *)invocation; 229 | 230 | /*! 231 | Returns whether the application should be relaunched at all. 232 | 233 | Some apps \b cannot be relaunched under certain circumstances. 234 | This method can be used to explicitly prevent a relaunch. 235 | 236 | \param updater The SUUpdater instance. 237 | */ 238 | - (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater; 239 | 240 | /*! 241 | Called immediately before relaunching. 242 | 243 | \param updater The SUUpdater instance. 244 | */ 245 | - (void)updaterWillRelaunchApplication:(SUUpdater *)updater; 246 | 247 | /*! 248 | Returns an object that compares version numbers to determine their arithmetic relation to each other. 249 | 250 | This method allows you to provide a custom version comparator. 251 | If you don't implement this method or return \c nil, 252 | the standard version comparator will be used. 253 | 254 | \sa SUStandardVersionComparator 255 | 256 | \param updater The SUUpdater instance. 257 | */ 258 | - (id)versionComparatorForUpdater:(SUUpdater *)updater; 259 | 260 | /*! 261 | Returns an object that formats version numbers for display to the user. 262 | 263 | If you don't implement this method or return \c nil, 264 | the standard version formatter will be used. 265 | 266 | \sa SUUpdateAlert 267 | 268 | \param updater The SUUpdater instance. 269 | */ 270 | - (id)versionDisplayerForUpdater:(SUUpdater *)updater; 271 | 272 | /*! 273 | Returns the path which is used to relaunch the client after the update is installed. 274 | 275 | The default is the path of the host bundle. 276 | 277 | \param updater The SUUpdater instance. 278 | */ 279 | - (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; 280 | 281 | /*! 282 | Called before an updater shows a modal alert window, 283 | to give the host the opportunity to hide attached windows that may get in the way. 284 | 285 | \param updater The SUUpdater instance. 286 | */ 287 | - (void)updaterWillShowModalAlert:(SUUpdater *)updater; 288 | 289 | /*! 290 | Called after an updater shows a modal alert window, 291 | to give the host the opportunity to hide attached windows that may get in the way. 292 | 293 | \param updater The SUUpdater instance. 294 | */ 295 | - (void)updaterDidShowModalAlert:(SUUpdater *)updater; 296 | 297 | /*! 298 | Called when an update is scheduled to be silently installed on quit. 299 | 300 | \param updater The SUUpdater instance. 301 | \param item The appcast item corresponding to the update that is proposed to be installed. 302 | \param invocation Can be used to trigger an immediate silent install and relaunch. 303 | */ 304 | - (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation; 305 | 306 | /*! 307 | Calls after an update that was scheduled to be silently installed on quit has been canceled. 308 | 309 | \param updater The SUUpdater instance. 310 | \param item The appcast item corresponding to the update that was proposed to be installed. 311 | */ 312 | - (void)updater:(SUUpdater *)updater didCancelInstallUpdateOnQuit:(SUAppcastItem *)item; 313 | 314 | @end 315 | 316 | 317 | // ----------------------------------------------------------------------------- 318 | // Constants: 319 | // ----------------------------------------------------------------------------- 320 | 321 | // Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. 322 | #if defined(DEBUG) && DEBUG && 0 323 | #define SU_MIN_CHECK_INTERVAL 60 324 | #else 325 | #define SU_MIN_CHECK_INTERVAL 60 * 60 326 | #endif 327 | 328 | #if defined(DEBUG) && DEBUG && 0 329 | #define SU_DEFAULT_CHECK_INTERVAL 60 330 | #else 331 | #define SU_DEFAULT_CHECK_INTERVAL 60 * 60 * 24 332 | #endif 333 | 334 | #endif 335 | -------------------------------------------------------------------------------- /Messenger/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import 3 | #import "jsapi.h" 4 | #import "WebPreferences.h" 5 | #import "JSClass.hh" 6 | #import "MEmbeddedRes.h" 7 | 8 | static BOOL kCFIsOSX_10_10_orNewer; 9 | 10 | static void __attribute__((constructor))_init() { 11 | kCFIsOSX_10_10_orNewer = floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9; 12 | } 13 | 14 | @interface AppDelegate () 15 | @property (nonatomic, readonly) BOOL canMakeTextLarger; 16 | - (IBAction)makeTextLarger:(id)sender; 17 | @property (nonatomic, readonly) BOOL canMakeTextSmaller; 18 | - (IBAction)makeTextSmaller:(id)sender; 19 | @property (nonatomic, readonly) BOOL canMakeTextStandardSize; 20 | - (IBAction)makeTextStandardSize:(id)sender; 21 | @end 22 | 23 | @implementation AppDelegate { 24 | NSWindow* _window; 25 | WebView* _webView; 26 | NSView* _titlebarView; // NSTitlebarView 27 | NSString* _lastNotificationCount; 28 | } 29 | 30 | - (void)applicationDidFinishLaunching:(NSNotification*)notification { 31 | // Register ourselves as the default-user-notification center delegate 32 | [NSUserNotificationCenter defaultUserNotificationCenter].delegate = self; 33 | 34 | // Create main window 35 | NSUInteger windowStyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask; 36 | if (kCFIsOSX_10_10_orNewer) { 37 | windowStyle |= NSFullSizeContentViewWindowMask; 38 | } 39 | _window = [[NSWindow alloc] initWithContentRect:{{0,0},{800,600}} styleMask:windowStyle backing:NSBackingStoreBuffered defer:YES]; 40 | if (kCFIsOSX_10_10_orNewer) { 41 | _window.appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]; 42 | _window.titleVisibility = NSWindowTitleHidden; 43 | _window.titlebarAppearsTransparent = YES; 44 | } 45 | _window.minSize = {640,400}; 46 | _window.releasedWhenClosed = NO; 47 | _window.delegate = self; 48 | [_window center]; 49 | _window.frameAutosaveName = @"main"; 50 | 51 | if (kCFIsOSX_10_10_orNewer) { 52 | // Hack to hide "traffic lights" but still allowing window manipulation (which isn't the case if we use proper window flags) 53 | _titlebarView = [_window standardWindowButton:NSWindowCloseButton].superview; 54 | _titlebarView.wantsLayer = YES; 55 | _titlebarView.layer.opacity = 0.0; 56 | auto titlebarTrackingArea = [[NSTrackingArea alloc] initWithRect:_titlebarView.bounds options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp owner:self userInfo:nil]; 57 | [_titlebarView addTrackingArea:titlebarTrackingArea]; 58 | } 59 | 60 | // App data 61 | auto appDataDir = [NSString stringWithFormat:@"~/Library/Application Support/%@", [NSBundle mainBundle].bundleIdentifier].stringByExpandingTildeInPath; 62 | 63 | // Web prefs 64 | auto wp = [[WebPreferences alloc] initWithIdentifier:@"main"]; 65 | [wp _setLocalStorageDatabasePath:[appDataDir stringByAppendingPathComponent:@"localstorage"]]; 66 | #define ENABLE(k) do { wp.k = YES; } while(0) 67 | #define DISABLE(k) do { wp.k = NO; } while(0) 68 | #define PRINT(k) NSLog(@"%s: %s", #k, wp.k ? "y" : "n") 69 | // PRINT(showDebugBorders); 70 | // PRINT(showRepaintCounter); 71 | 72 | // Official settings 73 | DISABLE(javaEnabled); 74 | ENABLE(autosaves); // saves to user defaults with keys prefixed `identifier` 75 | 76 | // Unofficial/Private settings 77 | ENABLE(acceleratedCompositingEnabled); 78 | ENABLE(acceleratedDrawingEnabled); 79 | ENABLE(accelerated2dCanvasEnabled); 80 | ENABLE(offlineWebApplicationCacheEnabled); 81 | ENABLE(localStorageEnabled); 82 | ENABLE(webAudioEnabled); 83 | DISABLE(usesEncodingDetector); 84 | DISABLE(usePreHTML5ParserQuirks); 85 | DISABLE(useLegacyTextAlignPositionedElementBehavior); 86 | DISABLE(textAreasAreResizable); 87 | DISABLE(mediaPlaybackRequiresUserGesture); 88 | ENABLE(mediaPlaybackAllowsInline); 89 | ENABLE(hixie76WebSocketProtocolEnabled); 90 | //ENABLE(frameFlatteningEnabled); 91 | ENABLE(fullScreenEnabled); 92 | ENABLE(hiddenPageCSSAnimationSuspensionEnabled); 93 | ENABLE(hiddenPageDOMTimerThrottlingEnabled); 94 | DISABLE(backspaceKeyNavigationEnabled); 95 | if (kCFIsOSX_10_10_orNewer) { 96 | ENABLE(subpixelCSSOMElementMetricsEnabled); 97 | } 98 | 99 | // Security relaxation 100 | //DISABLE(XSSAuditorEnabled); 101 | //DISABLE(WebSecurityEnabled); 102 | //DISABLE(hyperlinkAuditingEnabled); 103 | 104 | // Dev 105 | #if DEBUG 106 | ENABLE(developerExtrasEnabled); 107 | #endif 108 | #undef ENABLE 109 | #undef DISABLE 110 | #undef PRINT 111 | 112 | // Web view in main window 113 | auto webView = [[WebView alloc] initWithFrame:{{0,0},{100,100}} frameName:@"main" groupName:@"main"]; 114 | _window.contentView = webView; 115 | webView.policyDelegate = self; 116 | webView.frameLoadDelegate = self; 117 | webView.UIDelegate = self; 118 | webView.preferences = wp; 119 | auto req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.messenger.com/t/"]]; 120 | [webView.mainFrame loadRequest:req]; 121 | _webView = webView; 122 | 123 | // Present main window 124 | [_window makeKeyAndOrderFront:self]; 125 | 126 | //- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag; 127 | 128 | // Sparkle 129 | auto su = [SUUpdater sharedUpdater]; 130 | su.automaticallyChecksForUpdates = YES; 131 | su.automaticallyDownloadsUpdates = YES; 132 | su.feedURL = [NSURL URLWithString:@"http://fbmacmessenger.rsms.me/changelog.xml"]; 133 | [su checkForUpdatesInBackground]; 134 | 135 | _lastNotificationCount = @""; 136 | } 137 | 138 | - (void)setActiveConversationAtIndex:(NSString*)index { 139 | [_webView.windowScriptObject evaluateWebScript: 140 | [NSString stringWithFormat: 141 | @"document.querySelector('li:nth-child(%@) > [data-reactid]:first-child').click();", index]]; 142 | } 143 | 144 | - (void)mouseEntered:(NSEvent*)ev { 145 | // titlebar 146 | _titlebarView.layer.opacity = 1; 147 | } 148 | 149 | 150 | - (void)mouseExited:(NSEvent*)ev { 151 | // titlebar 152 | _titlebarView.layer.opacity = 0; 153 | } 154 | 155 | - (IBAction)find:(NSMenuItem*)sender { 156 | // Give input focus to the search field 157 | [_webView.windowScriptObject evaluateWebScript:@"document.querySelector('input[placeholder~=\"Search\"]').focus();"]; 158 | } 159 | 160 | 161 | - (IBAction)checkForUpdates:(id)sender { 162 | [[SUUpdater sharedUpdater] checkForUpdates:self]; 163 | } 164 | 165 | 166 | - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { 167 | [_window makeKeyAndOrderFront:self]; 168 | return YES; 169 | } 170 | 171 | - (void)applicationDidBecomeActive:(NSNotification *)notification { 172 | [_window makeKeyAndOrderFront:self]; 173 | } 174 | 175 | 176 | #pragma mark - WebView proxies 177 | 178 | - (BOOL)canMakeTextLarger { return _webView.canMakeTextLarger; } 179 | - (IBAction)makeTextLarger:(id)sender { [_webView makeTextLarger:sender]; } 180 | - (BOOL)canMakeTextSmaller { return _webView.canMakeTextSmaller; } 181 | - (IBAction)makeTextSmaller:(id)sender { [_webView makeTextSmaller:sender]; } 182 | - (BOOL)canMakeTextStandardSize { return _webView.canMakeTextStandardSize; } 183 | - (IBAction)makeTextStandardSize:(id)sender { [_webView makeTextStandardSize:sender]; } 184 | 185 | 186 | #pragma mark - NSWindowDelegate 187 | 188 | 189 | - (void)windowDidBecomeKey:(NSNotification*)notification { 190 | //NSLog(@"%@%@%@", self, NSStringFromSelector(_cmd), notification); 191 | // Give focus to the composer 192 | [_webView.windowScriptObject evaluateWebScript:@"document.querySelector('div[contenteditable=\"true\"]').focus();"]; 193 | } 194 | 195 | 196 | #pragma mark - NSUserNotificationCenterDelegate 197 | 198 | 199 | - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center 200 | shouldPresentNotification:(NSUserNotification*)notification { 201 | //NSLog(@"%@%@%@", self, NSStringFromSelector(_cmd), notification); 202 | return YES; 203 | } 204 | 205 | 206 | - (void)userNotificationCenter:(NSUserNotificationCenter*)center 207 | didActivateNotification:(NSUserNotification*)notification { 208 | //NSLog(@"%@%@ notification=%@", self, NSStringFromSelector(_cmd), notification); 209 | if (notification.userInfo && notification.userInfo[@"isJSNotification"]) { 210 | JSNotificationsActivateNotification(_webView.mainFrame.globalContext, notification); 211 | } 212 | } 213 | 214 | 215 | #pragma mark - WebUIDelegate 216 | 217 | 218 | - (NSUInteger)webView:(WebView *)webView dragDestinationActionMaskForDraggingInfo:(id )draggingInfo { 219 | // This method is called periodically as something is dragged over a WebView. 220 | // The UI delegate can return a mask indicating which drag destination actions can occur, 221 | // WebDragDestinationActionAny to allow any kind of action or WebDragDestinationActionNone 222 | // to not accept the drag. 223 | // NSLog(@"%@%@ draggingInfo=%@", self, NSStringFromSelector(_cmd), draggingInfo); 224 | return WebDragDestinationActionDHTML; 225 | } 226 | 227 | 228 | - (void)webView:(WebView*)webView runOpenPanelForFileButtonWithResultListener:(id)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles { 229 | //NSLog(@"%@%@ resultListener=%@", self, NSStringFromSelector(_cmd), resultListener); 230 | auto openPanel = [NSOpenPanel openPanel]; 231 | openPanel.canChooseDirectories = NO; 232 | openPanel.canChooseFiles = YES; 233 | openPanel.allowsMultipleSelection = allowMultipleFiles; 234 | openPanel.resolvesAliases = YES; 235 | openPanel.canResolveUbiquitousConflicts = YES; 236 | openPanel.canDownloadUbiquitousContents = YES; 237 | openPanel.canCreateDirectories = YES; 238 | openPanel.title = @"Select files"; 239 | 240 | auto ud = [NSUserDefaults standardUserDefaults]; 241 | auto dirURL = [ud URLForKey:@"open-dialog-url"]; 242 | if (!dirURL) { 243 | dirURL = [NSURL fileURLWithPath:NSHomeDirectory() isDirectory:YES]; 244 | } 245 | 246 | openPanel.directoryURL = dirURL; 247 | 248 | auto onComplete = ^(NSInteger result) { 249 | [ud setURL:openPanel.directoryURL forKey:@"open-dialog-url"]; 250 | if (result == 1) { 251 | auto filenames = [NSMutableArray arrayWithCapacity:openPanel.URLs.count]; 252 | for (NSURL* url in openPanel.URLs) { 253 | [filenames addObject:url.absoluteURL.path]; 254 | } 255 | [resultListener chooseFilenames:filenames]; 256 | } else { 257 | [resultListener cancel]; 258 | } 259 | }; 260 | [openPanel beginSheetModalForWindow:_window completionHandler:onComplete]; 261 | } 262 | 263 | 264 | 265 | #pragma mark - WebFrameLoadDelegate 266 | 267 | 268 | - (void)webView:(WebView *)webView didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame { 269 | auto ctx = webView.mainFrame.globalContext; 270 | JSObjectRef globalObj = JSContextGetGlobalObject(ctx); 271 | 272 | auto Notifications = JSNotificationsCreate(ctx, 0, nullptr, nullptr); 273 | JSClass::setProperty(ctx, globalObj, u"_notifications", Notifications); 274 | 275 | 276 | auto NotificationCons = JSObjectMakeConstructor(ctx, JSNotificationJSClass(), JSNotificationConstruct); 277 | 278 | auto s = U16JSStr(u"granted"); 279 | JSClass::setProperty(ctx, NotificationCons, u"permission", JSValueMakeString(ctx, s)); 280 | JSStringRelease(s); 281 | 282 | s = U16JSStr(u"requestPermission"); 283 | auto paramName = U16JSStr(u"callback"); 284 | auto bodys = U16JSStr(u"console.log('requestPermission'); callback(\"granted\");"); 285 | auto f = JSObjectMakeFunction(ctx, s, 1, ¶mName, bodys, nullptr, 1, nullptr); 286 | JSClass::setProperty(ctx, NotificationCons, u"requestPermission", f); 287 | JSStringRelease(paramName); 288 | JSStringRelease(bodys); 289 | JSStringRelease(s); 290 | 291 | JSClass::setProperty(ctx, globalObj, u"Notification", NotificationCons); 292 | 293 | // WARNING! Fragile hack to automatically enable desktop notifications: 294 | // auto r = [webView.mainFrame.windowObject evaluateWebScript: 295 | // @"var v = {__t:(new Date).getTime(),__v:true}; localStorage._cs_desktopNotifsEnabled = v; localStorage.setItem('_cs_desktopNotifsEnabled',JSON.stringify(v));"]; 296 | // NSLog(@"r: %@", r); 297 | 298 | } 299 | 300 | 301 | - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame { 302 | auto rsp = frame.dataSource.response; 303 | if ([rsp isKindOfClass:[NSHTTPURLResponse class]] && ((NSHTTPURLResponse*)rsp).statusCode == 400) { 304 | NSLog(@"%@%@ frame.dataSource.response=%@", self, NSStringFromSelector(_cmd), frame.dataSource.response); 305 | [webView.mainFrame.windowObject evaluateWebScript: 306 | [NSString stringWithFormat:@"document.body.innerText = ''; var e = document.createElement('p'); document.body.appendChild(e); e.innerText = 'Oh noes. It appears Messenger.com is down for maintenance. Please try again later.'; var s = e.style; s.font='18px helvetica-light'; s.lineHeight='27px'; s.color='#999'; s.margin='0 auto'; s.width='50%%'; s.textAlign='center'; s.margin='0 auto'; s.marginTop='100px'; s.marginBottom='30px'; s.width='235px'; s.height='235px'; s.paddingTop='250px'; s.backgroundRepeat='no-repeat'; s.backgroundPosition='top center'; s.backgroundImage='url(%@)';", kErrorPNGDataURL]]; 307 | } 308 | } 309 | 310 | -(void)webView:(WebView *)webView didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { 311 | NSLog(@"%@%@ error=%@", self, NSStringFromSelector(_cmd), error); 312 | [webView.mainFrame.windowObject evaluateWebScript: 313 | [NSString stringWithFormat:@"document.body.innerText = ''; var e = document.createElement('p'); document.body.appendChild(e); e.innerText = 'Oh snap. It looks like your connection is offline, please try again later.'; var s = e.style; s.font='18px helvetica-light'; s.lineHeight='27px'; s.color='#999'; s.margin='0 auto'; s.width='50%%'; s.textAlign='center'; s.margin='0 auto'; s.marginTop='100px'; s.marginBottom='30px'; s.width='235px'; s.height='235px'; s.paddingTop='250px'; s.backgroundRepeat='no-repeat'; s.backgroundPosition='top center'; s.backgroundImage='url(%@)';", kErrorPNGDataURL]]; 314 | } 315 | 316 | - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { 317 | NSString* notificationCount = _lastNotificationCount; 318 | 319 | if ([title isEqualToString:@"Messenger"]) { 320 | notificationCount = @""; 321 | } else { 322 | NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"\\(([0-9]+)\\) Messenger" options:0 error:nil]; 323 | NSTextCheckingResult* match = [regex firstMatchInString:title options:0 range:NSMakeRange(0, [title length])]; 324 | 325 | if (match) { 326 | notificationCount = [title substringWithRange:[match rangeAtIndex:1]]; 327 | } 328 | } 329 | 330 | if (![notificationCount isEqualTo:_lastNotificationCount]) { 331 | [[NSApp dockTile] setBadgeLabel: notificationCount]; 332 | _lastNotificationCount = notificationCount; 333 | } 334 | } 335 | 336 | 337 | #pragma mark - WebPolicyDelegate 338 | 339 | - (void)webView:(WebView *)sender 340 | decidePolicyForNavigationAction:(NSDictionary *)actionInformation 341 | request:(NSURLRequest *)request 342 | frame:(WebFrame *)frame 343 | decisionListener:(id)listener 344 | { 345 | //NSLog(@"%@%@ actionInformation=%@ request=%@", self, NSStringFromSelector(_cmd), actionInformation, request); 346 | NSURL* url = [[actionInformation objectForKey:WebActionOriginalURLKey] absoluteURL]; 347 | if ([url.host isEqualToString:@"www.messenger.com"] || 348 | ([url.host isEqualToString:@"www.facebook.com"] && 349 | ([url.path hasPrefix:@"/login/"] || [url.path hasPrefix:@"/checkpoint/"] || [url.path isEqualToString:@"/checkpoint"]) 350 | ) ) 351 | { 352 | [listener use]; 353 | } else { 354 | [self openWorkspaceURL:url]; 355 | [listener ignore]; 356 | } 357 | } 358 | 359 | 360 | - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id)listener { 361 | // Open all "new window" links in the browser 362 | //NSLog(@"%@%@ actionInformation=%@ request=%@", self, NSStringFromSelector(_cmd), actionInformation, request); 363 | NSURL* url = [actionInformation objectForKey:WebActionOriginalURLKey]; 364 | [self openWorkspaceURL:url]; 365 | [listener ignore]; 366 | } 367 | 368 | 369 | - (void)openWorkspaceURL:(NSURL*)url { 370 | if ([url.path hasPrefix:@"/l.php"]) { 371 | // Make things a bit faster by bypassing Facebook's link filter, which sometimes traps completely 372 | // legit URLs as "phishing" (like the website for this app!) 373 | for (NSString* kv in [url.query componentsSeparatedByString:@"&"]) { 374 | auto r = [kv rangeOfString:@"=" options:NSLiteralSearch]; 375 | if (r.location != NSNotFound && [[kv substringToIndex:r.location] isEqualToString:@"u"]) { 376 | auto encodedURL = [kv substringFromIndex:r.location + r.length]; 377 | url = [NSURL URLWithString:[encodedURL stringByRemovingPercentEncoding]]; 378 | } 379 | } 380 | } 381 | [[NSWorkspace sharedWorkspace] openURL:url]; 382 | } 383 | 384 | 385 | @end 386 | -------------------------------------------------------------------------------- /Messenger/MEmbeddedRes.m: -------------------------------------------------------------------------------- 1 | #import "MEmbeddedRes.h" 2 | 3 | NSString* kErrorPNGDataURL = @"data:image/png;base64,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"; 4 | --------------------------------------------------------------------------------