├── .gitignore ├── ExtensionsForSafari.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── ExtensionsForSafari.xcworkspace └── contents.xcworkspacedata ├── ExtensionsForSafari ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── ActionIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon-Spotlight-40.png │ │ ├── Icon-Spotlight-40@2x.png │ │ └── Icon-Spotlight-40@3x.png │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon-Spotlight-40.png │ │ ├── Icon-Spotlight-40@2x.png │ │ └── Icon-Spotlight-40@3x.png │ ├── Brand Assets.launchimage │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CodeMirror │ ├── html │ │ └── sublime.html │ ├── lib │ │ ├── codemirror.css │ │ └── codemirror.js │ ├── mode │ │ └── javascript │ │ │ ├── index.html │ │ │ ├── javascript.js │ │ │ ├── json-ld.html │ │ │ ├── test.js │ │ │ └── typescript.html │ └── theme │ │ └── monokai.css ├── CodeSnippet.h ├── CodeSnippet.m ├── EditorViewController.h ├── EditorViewController.m ├── ExtensionsForSafari.entitlements ├── Info.plist ├── SnippetTableViewCell.h ├── SnippetTableViewCell.m ├── SnippetTableViewCell.xib ├── SnippetsTableViewController.h ├── SnippetsTableViewController.m └── main.m ├── ExtensionsForSafariAction ├── ActionViewController.h ├── ActionViewController.m ├── Base.lproj │ └── MainInterface.storyboard ├── ExtensionsForSafariAction.entitlements ├── Info.plist └── Inject.js ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── screenshot1.PNG ├── screenshot2.PNG └── screenshot3.PNG /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | .DS_Store 20 | 21 | # CocoaPods 22 | # 23 | # We recommend against adding the Pods directory to your .gitignore. However 24 | # you should judge for yourself, the pros and cons are mentioned at: 25 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 26 | # 27 | Pods/ 28 | -------------------------------------------------------------------------------- /ExtensionsForSafari.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2AC4AADA8E3B6A61F1C111FB /* Pods_ExtensionsForSafari.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1365CA4885D9A94EBE68004 /* Pods_ExtensionsForSafari.framework */; }; 11 | 947AB3181D767B5700B427D8 /* CodeSnippet.m in Sources */ = {isa = PBXBuildFile; fileRef = 947AB3171D767B5700B427D8 /* CodeSnippet.m */; }; 12 | 94916ABF1D76C09100181750 /* Inject.js in Resources */ = {isa = PBXBuildFile; fileRef = 94916ABE1D76C09100181750 /* Inject.js */; }; 13 | 94916AC31D76C55600181750 /* CodeSnippet.m in Sources */ = {isa = PBXBuildFile; fileRef = 947AB3171D767B5700B427D8 /* CodeSnippet.m */; }; 14 | 94916AC41D76C55C00181750 /* CodeSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = 947AB3161D767B5700B427D8 /* CodeSnippet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 94916ACA1D76CA7C00181750 /* SnippetTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 94916AC71D76CA7C00181750 /* SnippetTableViewCell.h */; }; 16 | 94916ACB1D76CA7C00181750 /* SnippetTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 94916AC81D76CA7C00181750 /* SnippetTableViewCell.m */; }; 17 | 94916ACC1D76CA7C00181750 /* SnippetTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94916AC91D76CA7C00181750 /* SnippetTableViewCell.xib */; }; 18 | 94916ACD1D76CAF600181750 /* SnippetTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94916AC91D76CA7C00181750 /* SnippetTableViewCell.xib */; }; 19 | 94916ACE1D76CAF900181750 /* SnippetTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 94916AC81D76CA7C00181750 /* SnippetTableViewCell.m */; }; 20 | 94916ACF1D76DB2700181750 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 94E850AE1D75759C0012027E /* Assets.xcassets */; }; 21 | 9493E9DD1D766CEE006B4A4B /* SnippetsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9493E9DC1D766CEE006B4A4B /* SnippetsTableViewController.m */; }; 22 | 94E850A41D75759C0012027E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94E850A31D75759C0012027E /* main.m */; }; 23 | 94E850A71D75759C0012027E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 94E850A61D75759C0012027E /* AppDelegate.m */; }; 24 | 94E850AD1D75759C0012027E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 94E850AB1D75759C0012027E /* Main.storyboard */; }; 25 | 94E850AF1D75759C0012027E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 94E850AE1D75759C0012027E /* Assets.xcassets */; }; 26 | 94E850B21D75759C0012027E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 94E850B01D75759C0012027E /* LaunchScreen.storyboard */; }; 27 | 94E850C11D7575BE0012027E /* ActionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94E850C01D7575BE0012027E /* ActionViewController.m */; }; 28 | 94E850C41D7575BE0012027E /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 94E850C21D7575BE0012027E /* MainInterface.storyboard */; }; 29 | 94E850C81D7575BE0012027E /* ExtensionsForSafariAction.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 94E850BD1D7575BE0012027E /* ExtensionsForSafariAction.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 30 | 94E850CE1D75760F0012027E /* CodeMirror in Resources */ = {isa = PBXBuildFile; fileRef = 94E850CD1D75760F0012027E /* CodeMirror */; }; 31 | 94E850CF1D75760F0012027E /* CodeMirror in Resources */ = {isa = PBXBuildFile; fileRef = 94E850CD1D75760F0012027E /* CodeMirror */; }; 32 | 94E850D21D7576C40012027E /* EditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94E850D11D7576C40012027E /* EditorViewController.m */; }; 33 | CA316401A16A079C4A6FA837 /* Pods_ExtensionsForSafariAction.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE9EF2EB8F547DEDA950A56B /* Pods_ExtensionsForSafariAction.framework */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | 94E850C61D7575BE0012027E /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 94E850971D75759C0012027E /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 94E850BC1D7575BE0012027E; 42 | remoteInfo = ExtensionsForSafariAction; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXCopyFilesBuildPhase section */ 47 | 94E850CC1D7575BE0012027E /* Embed App Extensions */ = { 48 | isa = PBXCopyFilesBuildPhase; 49 | buildActionMask = 2147483647; 50 | dstPath = ""; 51 | dstSubfolderSpec = 13; 52 | files = ( 53 | 94E850C81D7575BE0012027E /* ExtensionsForSafariAction.appex in Embed App Extensions */, 54 | ); 55 | name = "Embed App Extensions"; 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXCopyFilesBuildPhase section */ 59 | 60 | /* Begin PBXFileReference section */ 61 | 138DD21EB9F47D0C2B736A60 /* Pods-ExtensionsForSafariAction.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExtensionsForSafariAction.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExtensionsForSafariAction/Pods-ExtensionsForSafariAction.release.xcconfig"; sourceTree = ""; }; 62 | 4D07D1B8708D4E1CA0129F99 /* Pods-ExtensionsForSafari.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExtensionsForSafari.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExtensionsForSafari/Pods-ExtensionsForSafari.release.xcconfig"; sourceTree = ""; }; 63 | 5CBE8BC6EE4505EA492D9E16 /* Pods-ExtensionsForSafari.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExtensionsForSafari.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExtensionsForSafari/Pods-ExtensionsForSafari.debug.xcconfig"; sourceTree = ""; }; 64 | 947AB3161D767B5700B427D8 /* CodeSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSnippet.h; sourceTree = ""; }; 65 | 947AB3171D767B5700B427D8 /* CodeSnippet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeSnippet.m; sourceTree = ""; }; 66 | 94916ABC1D76BE0700181750 /* ExtensionsForSafari.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = ExtensionsForSafari.entitlements; sourceTree = ""; }; 67 | 94916ABD1D76BE2900181750 /* ExtensionsForSafariAction.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = ExtensionsForSafariAction.entitlements; sourceTree = ""; }; 68 | 94916ABE1D76C09100181750 /* Inject.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = Inject.js; sourceTree = ""; }; 69 | 94916AC71D76CA7C00181750 /* SnippetTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetTableViewCell.h; sourceTree = ""; }; 70 | 94916AC81D76CA7C00181750 /* SnippetTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnippetTableViewCell.m; sourceTree = ""; }; 71 | 94916AC91D76CA7C00181750 /* SnippetTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SnippetTableViewCell.xib; sourceTree = ""; }; 72 | 9493E9DB1D766CEE006B4A4B /* SnippetsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetsTableViewController.h; sourceTree = ""; }; 73 | 9493E9DC1D766CEE006B4A4B /* SnippetsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnippetsTableViewController.m; sourceTree = ""; }; 74 | 94E8509F1D75759C0012027E /* ExtensionsForSafari.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExtensionsForSafari.app; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | 94E850A31D75759C0012027E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 76 | 94E850A51D75759C0012027E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 77 | 94E850A61D75759C0012027E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 78 | 94E850AC1D75759C0012027E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 79 | 94E850AE1D75759C0012027E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 80 | 94E850B11D75759C0012027E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 81 | 94E850B31D75759C0012027E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 82 | 94E850BD1D7575BE0012027E /* ExtensionsForSafariAction.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ExtensionsForSafariAction.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | 94E850BF1D7575BE0012027E /* ActionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActionViewController.h; sourceTree = ""; }; 84 | 94E850C01D7575BE0012027E /* ActionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ActionViewController.m; sourceTree = ""; }; 85 | 94E850C31D7575BE0012027E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 86 | 94E850C51D7575BE0012027E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 87 | 94E850CD1D75760F0012027E /* CodeMirror */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CodeMirror; sourceTree = ""; }; 88 | 94E850D01D7576C40012027E /* EditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditorViewController.h; sourceTree = ""; }; 89 | 94E850D11D7576C40012027E /* EditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditorViewController.m; sourceTree = ""; }; 90 | BE9EF2EB8F547DEDA950A56B /* Pods_ExtensionsForSafariAction.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExtensionsForSafariAction.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | CC182BEBBB2FAF996D2E62B2 /* Pods-ExtensionsForSafariAction.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExtensionsForSafariAction.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExtensionsForSafariAction/Pods-ExtensionsForSafariAction.debug.xcconfig"; sourceTree = ""; }; 92 | E1365CA4885D9A94EBE68004 /* Pods_ExtensionsForSafari.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExtensionsForSafari.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 93 | /* End PBXFileReference section */ 94 | 95 | /* Begin PBXFrameworksBuildPhase section */ 96 | 94E8509C1D75759C0012027E /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | 2AC4AADA8E3B6A61F1C111FB /* Pods_ExtensionsForSafari.framework in Frameworks */, 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | 94E850BA1D7575BE0012027E /* Frameworks */ = { 105 | isa = PBXFrameworksBuildPhase; 106 | buildActionMask = 2147483647; 107 | files = ( 108 | CA316401A16A079C4A6FA837 /* Pods_ExtensionsForSafariAction.framework in Frameworks */, 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | /* End PBXFrameworksBuildPhase section */ 113 | 114 | /* Begin PBXGroup section */ 115 | 94E850961D75759C0012027E = { 116 | isa = PBXGroup; 117 | children = ( 118 | 94E850A11D75759C0012027E /* ExtensionsForSafari */, 119 | 94E850BE1D7575BE0012027E /* ExtensionsForSafariAction */, 120 | 94E850A01D75759C0012027E /* Products */, 121 | A360ABD1295981E152A2380B /* Frameworks */, 122 | F0B44F539E2CDE09DD33937C /* Pods */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | 94E850A01D75759C0012027E /* Products */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 94E8509F1D75759C0012027E /* ExtensionsForSafari.app */, 130 | 94E850BD1D7575BE0012027E /* ExtensionsForSafariAction.appex */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | 94E850A11D75759C0012027E /* ExtensionsForSafari */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 94916ABC1D76BE0700181750 /* ExtensionsForSafari.entitlements */, 139 | 94E850CD1D75760F0012027E /* CodeMirror */, 140 | 94E850A51D75759C0012027E /* AppDelegate.h */, 141 | 94E850A61D75759C0012027E /* AppDelegate.m */, 142 | 947AB3161D767B5700B427D8 /* CodeSnippet.h */, 143 | 947AB3171D767B5700B427D8 /* CodeSnippet.m */, 144 | 94E850D01D7576C40012027E /* EditorViewController.h */, 145 | 94E850D11D7576C40012027E /* EditorViewController.m */, 146 | 9493E9DB1D766CEE006B4A4B /* SnippetsTableViewController.h */, 147 | 9493E9DC1D766CEE006B4A4B /* SnippetsTableViewController.m */, 148 | 94916AC71D76CA7C00181750 /* SnippetTableViewCell.h */, 149 | 94916AC81D76CA7C00181750 /* SnippetTableViewCell.m */, 150 | 94916AC91D76CA7C00181750 /* SnippetTableViewCell.xib */, 151 | 94E850AB1D75759C0012027E /* Main.storyboard */, 152 | 94E850AE1D75759C0012027E /* Assets.xcassets */, 153 | 94E850B01D75759C0012027E /* LaunchScreen.storyboard */, 154 | 94E850B31D75759C0012027E /* Info.plist */, 155 | 94E850A21D75759C0012027E /* Supporting Files */, 156 | ); 157 | path = ExtensionsForSafari; 158 | sourceTree = ""; 159 | }; 160 | 94E850A21D75759C0012027E /* Supporting Files */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 94E850A31D75759C0012027E /* main.m */, 164 | ); 165 | name = "Supporting Files"; 166 | sourceTree = ""; 167 | }; 168 | 94E850BE1D7575BE0012027E /* ExtensionsForSafariAction */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 94916ABD1D76BE2900181750 /* ExtensionsForSafariAction.entitlements */, 172 | 94E850BF1D7575BE0012027E /* ActionViewController.h */, 173 | 94E850C01D7575BE0012027E /* ActionViewController.m */, 174 | 94916ABE1D76C09100181750 /* Inject.js */, 175 | 94E850C21D7575BE0012027E /* MainInterface.storyboard */, 176 | 94E850C51D7575BE0012027E /* Info.plist */, 177 | ); 178 | path = ExtensionsForSafariAction; 179 | sourceTree = ""; 180 | }; 181 | A360ABD1295981E152A2380B /* Frameworks */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | E1365CA4885D9A94EBE68004 /* Pods_ExtensionsForSafari.framework */, 185 | BE9EF2EB8F547DEDA950A56B /* Pods_ExtensionsForSafariAction.framework */, 186 | ); 187 | name = Frameworks; 188 | sourceTree = ""; 189 | }; 190 | F0B44F539E2CDE09DD33937C /* Pods */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 5CBE8BC6EE4505EA492D9E16 /* Pods-ExtensionsForSafari.debug.xcconfig */, 194 | 4D07D1B8708D4E1CA0129F99 /* Pods-ExtensionsForSafari.release.xcconfig */, 195 | CC182BEBBB2FAF996D2E62B2 /* Pods-ExtensionsForSafariAction.debug.xcconfig */, 196 | 138DD21EB9F47D0C2B736A60 /* Pods-ExtensionsForSafariAction.release.xcconfig */, 197 | ); 198 | name = Pods; 199 | sourceTree = ""; 200 | }; 201 | /* End PBXGroup section */ 202 | 203 | /* Begin PBXHeadersBuildPhase section */ 204 | 94916AC11D76C52F00181750 /* Headers */ = { 205 | isa = PBXHeadersBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | 94916ACA1D76CA7C00181750 /* SnippetTableViewCell.h in Headers */, 209 | 94916AC41D76C55C00181750 /* CodeSnippet.h in Headers */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXHeadersBuildPhase section */ 214 | 215 | /* Begin PBXNativeTarget section */ 216 | 94E8509E1D75759C0012027E /* ExtensionsForSafari */ = { 217 | isa = PBXNativeTarget; 218 | buildConfigurationList = 94E850B61D75759C0012027E /* Build configuration list for PBXNativeTarget "ExtensionsForSafari" */; 219 | buildPhases = ( 220 | 734FB0945C2205DB31751B36 /* [CP] Check Pods Manifest.lock */, 221 | 94E8509B1D75759C0012027E /* Sources */, 222 | 94E8509C1D75759C0012027E /* Frameworks */, 223 | 94E8509D1D75759C0012027E /* Resources */, 224 | 94E850CC1D7575BE0012027E /* Embed App Extensions */, 225 | EB68A9AA89583BF566B4A796 /* [CP] Embed Pods Frameworks */, 226 | CCE0E1DADF3BE363BA8704A2 /* [CP] Copy Pods Resources */, 227 | 94916AC11D76C52F00181750 /* Headers */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | 94E850C71D7575BE0012027E /* PBXTargetDependency */, 233 | ); 234 | name = ExtensionsForSafari; 235 | productName = ExtensionsForSafari; 236 | productReference = 94E8509F1D75759C0012027E /* ExtensionsForSafari.app */; 237 | productType = "com.apple.product-type.application"; 238 | }; 239 | 94E850BC1D7575BE0012027E /* ExtensionsForSafariAction */ = { 240 | isa = PBXNativeTarget; 241 | buildConfigurationList = 94E850C91D7575BE0012027E /* Build configuration list for PBXNativeTarget "ExtensionsForSafariAction" */; 242 | buildPhases = ( 243 | 2DC956EB58C5F05FB97F72FE /* [CP] Check Pods Manifest.lock */, 244 | 94E850B91D7575BE0012027E /* Sources */, 245 | 94E850BA1D7575BE0012027E /* Frameworks */, 246 | 94E850BB1D7575BE0012027E /* Resources */, 247 | 0579F1876601F9C7BDAFD501 /* [CP] Copy Pods Resources */, 248 | ); 249 | buildRules = ( 250 | ); 251 | dependencies = ( 252 | ); 253 | name = ExtensionsForSafariAction; 254 | productName = ExtensionsForSafariAction; 255 | productReference = 94E850BD1D7575BE0012027E /* ExtensionsForSafariAction.appex */; 256 | productType = "com.apple.product-type.app-extension"; 257 | }; 258 | /* End PBXNativeTarget section */ 259 | 260 | /* Begin PBXProject section */ 261 | 94E850971D75759C0012027E /* Project object */ = { 262 | isa = PBXProject; 263 | attributes = { 264 | LastUpgradeCheck = 0730; 265 | ORGANIZATIONNAME = JerryTian; 266 | TargetAttributes = { 267 | 94E8509E1D75759C0012027E = { 268 | CreatedOnToolsVersion = 7.3.1; 269 | DevelopmentTeam = LG59953R35; 270 | SystemCapabilities = { 271 | com.apple.ApplicationGroups.iOS = { 272 | enabled = 1; 273 | }; 274 | }; 275 | }; 276 | 94E850BC1D7575BE0012027E = { 277 | CreatedOnToolsVersion = 7.3.1; 278 | DevelopmentTeam = LG59953R35; 279 | SystemCapabilities = { 280 | com.apple.ApplicationGroups.iOS = { 281 | enabled = 1; 282 | }; 283 | }; 284 | }; 285 | }; 286 | }; 287 | buildConfigurationList = 94E8509A1D75759C0012027E /* Build configuration list for PBXProject "ExtensionsForSafari" */; 288 | compatibilityVersion = "Xcode 3.2"; 289 | developmentRegion = English; 290 | hasScannedForEncodings = 0; 291 | knownRegions = ( 292 | en, 293 | Base, 294 | ); 295 | mainGroup = 94E850961D75759C0012027E; 296 | productRefGroup = 94E850A01D75759C0012027E /* Products */; 297 | projectDirPath = ""; 298 | projectRoot = ""; 299 | targets = ( 300 | 94E8509E1D75759C0012027E /* ExtensionsForSafari */, 301 | 94E850BC1D7575BE0012027E /* ExtensionsForSafariAction */, 302 | ); 303 | }; 304 | /* End PBXProject section */ 305 | 306 | /* Begin PBXResourcesBuildPhase section */ 307 | 94E8509D1D75759C0012027E /* Resources */ = { 308 | isa = PBXResourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | 94E850CE1D75760F0012027E /* CodeMirror in Resources */, 312 | 94E850B21D75759C0012027E /* LaunchScreen.storyboard in Resources */, 313 | 94E850AF1D75759C0012027E /* Assets.xcassets in Resources */, 314 | 94E850AD1D75759C0012027E /* Main.storyboard in Resources */, 315 | 94916ACC1D76CA7C00181750 /* SnippetTableViewCell.xib in Resources */, 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | }; 319 | 94E850BB1D7575BE0012027E /* Resources */ = { 320 | isa = PBXResourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | 94E850CF1D75760F0012027E /* CodeMirror in Resources */, 324 | 94916ABF1D76C09100181750 /* Inject.js in Resources */, 325 | 94E850C41D7575BE0012027E /* MainInterface.storyboard in Resources */, 326 | 94916ACD1D76CAF600181750 /* SnippetTableViewCell.xib in Resources */, 327 | 94916ACF1D76DB2700181750 /* Assets.xcassets in Resources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | /* End PBXResourcesBuildPhase section */ 332 | 333 | /* Begin PBXShellScriptBuildPhase section */ 334 | 0579F1876601F9C7BDAFD501 /* [CP] Copy Pods Resources */ = { 335 | isa = PBXShellScriptBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | ); 339 | inputPaths = ( 340 | ); 341 | name = "[CP] Copy Pods Resources"; 342 | outputPaths = ( 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | shellPath = /bin/sh; 346 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExtensionsForSafariAction/Pods-ExtensionsForSafariAction-resources.sh\"\n"; 347 | showEnvVarsInLog = 0; 348 | }; 349 | 2DC956EB58C5F05FB97F72FE /* [CP] Check Pods Manifest.lock */ = { 350 | isa = PBXShellScriptBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | ); 354 | inputPaths = ( 355 | ); 356 | name = "[CP] Check Pods Manifest.lock"; 357 | outputPaths = ( 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | shellPath = /bin/sh; 361 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 362 | showEnvVarsInLog = 0; 363 | }; 364 | 734FB0945C2205DB31751B36 /* [CP] Check Pods Manifest.lock */ = { 365 | isa = PBXShellScriptBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | ); 369 | inputPaths = ( 370 | ); 371 | name = "[CP] Check Pods Manifest.lock"; 372 | outputPaths = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | shellPath = /bin/sh; 376 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 377 | showEnvVarsInLog = 0; 378 | }; 379 | CCE0E1DADF3BE363BA8704A2 /* [CP] Copy Pods Resources */ = { 380 | isa = PBXShellScriptBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | ); 384 | inputPaths = ( 385 | ); 386 | name = "[CP] Copy Pods Resources"; 387 | outputPaths = ( 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | shellPath = /bin/sh; 391 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExtensionsForSafari/Pods-ExtensionsForSafari-resources.sh\"\n"; 392 | showEnvVarsInLog = 0; 393 | }; 394 | EB68A9AA89583BF566B4A796 /* [CP] Embed Pods Frameworks */ = { 395 | isa = PBXShellScriptBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | ); 399 | inputPaths = ( 400 | ); 401 | name = "[CP] Embed Pods Frameworks"; 402 | outputPaths = ( 403 | ); 404 | runOnlyForDeploymentPostprocessing = 0; 405 | shellPath = /bin/sh; 406 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExtensionsForSafari/Pods-ExtensionsForSafari-frameworks.sh\"\n"; 407 | showEnvVarsInLog = 0; 408 | }; 409 | /* End PBXShellScriptBuildPhase section */ 410 | 411 | /* Begin PBXSourcesBuildPhase section */ 412 | 94E8509B1D75759C0012027E /* Sources */ = { 413 | isa = PBXSourcesBuildPhase; 414 | buildActionMask = 2147483647; 415 | files = ( 416 | 94E850A71D75759C0012027E /* AppDelegate.m in Sources */, 417 | 94916ACB1D76CA7C00181750 /* SnippetTableViewCell.m in Sources */, 418 | 9493E9DD1D766CEE006B4A4B /* SnippetsTableViewController.m in Sources */, 419 | 947AB3181D767B5700B427D8 /* CodeSnippet.m in Sources */, 420 | 94E850A41D75759C0012027E /* main.m in Sources */, 421 | 94E850D21D7576C40012027E /* EditorViewController.m in Sources */, 422 | ); 423 | runOnlyForDeploymentPostprocessing = 0; 424 | }; 425 | 94E850B91D7575BE0012027E /* Sources */ = { 426 | isa = PBXSourcesBuildPhase; 427 | buildActionMask = 2147483647; 428 | files = ( 429 | 94E850C11D7575BE0012027E /* ActionViewController.m in Sources */, 430 | 94916ACE1D76CAF900181750 /* SnippetTableViewCell.m in Sources */, 431 | 94916AC31D76C55600181750 /* CodeSnippet.m in Sources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | /* End PBXSourcesBuildPhase section */ 436 | 437 | /* Begin PBXTargetDependency section */ 438 | 94E850C71D7575BE0012027E /* PBXTargetDependency */ = { 439 | isa = PBXTargetDependency; 440 | target = 94E850BC1D7575BE0012027E /* ExtensionsForSafariAction */; 441 | targetProxy = 94E850C61D7575BE0012027E /* PBXContainerItemProxy */; 442 | }; 443 | /* End PBXTargetDependency section */ 444 | 445 | /* Begin PBXVariantGroup section */ 446 | 94E850AB1D75759C0012027E /* Main.storyboard */ = { 447 | isa = PBXVariantGroup; 448 | children = ( 449 | 94E850AC1D75759C0012027E /* Base */, 450 | ); 451 | name = Main.storyboard; 452 | sourceTree = ""; 453 | }; 454 | 94E850B01D75759C0012027E /* LaunchScreen.storyboard */ = { 455 | isa = PBXVariantGroup; 456 | children = ( 457 | 94E850B11D75759C0012027E /* Base */, 458 | ); 459 | name = LaunchScreen.storyboard; 460 | sourceTree = ""; 461 | }; 462 | 94E850C21D7575BE0012027E /* MainInterface.storyboard */ = { 463 | isa = PBXVariantGroup; 464 | children = ( 465 | 94E850C31D7575BE0012027E /* Base */, 466 | ); 467 | name = MainInterface.storyboard; 468 | sourceTree = ""; 469 | }; 470 | /* End PBXVariantGroup section */ 471 | 472 | /* Begin XCBuildConfiguration section */ 473 | 94E850B41D75759C0012027E /* Debug */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_SEARCH_USER_PATHS = NO; 477 | CLANG_ANALYZER_NONNULL = YES; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BOOL_CONVERSION = YES; 483 | CLANG_WARN_CONSTANT_CONVERSION = YES; 484 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 485 | CLANG_WARN_EMPTY_BODY = YES; 486 | CLANG_WARN_ENUM_CONVERSION = YES; 487 | CLANG_WARN_INT_CONVERSION = YES; 488 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 489 | CLANG_WARN_UNREACHABLE_CODE = YES; 490 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 491 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 492 | COPY_PHASE_STRIP = NO; 493 | DEBUG_INFORMATION_FORMAT = dwarf; 494 | ENABLE_STRICT_OBJC_MSGSEND = YES; 495 | ENABLE_TESTABILITY = YES; 496 | GCC_C_LANGUAGE_STANDARD = gnu99; 497 | GCC_DYNAMIC_NO_PIC = NO; 498 | GCC_NO_COMMON_BLOCKS = YES; 499 | GCC_OPTIMIZATION_LEVEL = 0; 500 | GCC_PREPROCESSOR_DEFINITIONS = ( 501 | "DEBUG=1", 502 | "$(inherited)", 503 | ); 504 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 505 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 506 | GCC_WARN_UNDECLARED_SELECTOR = YES; 507 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 508 | GCC_WARN_UNUSED_FUNCTION = YES; 509 | GCC_WARN_UNUSED_VARIABLE = YES; 510 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 511 | MTL_ENABLE_DEBUG_INFO = YES; 512 | ONLY_ACTIVE_ARCH = YES; 513 | SDKROOT = iphoneos; 514 | TARGETED_DEVICE_FAMILY = "1,2"; 515 | }; 516 | name = Debug; 517 | }; 518 | 94E850B51D75759C0012027E /* Release */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | ALWAYS_SEARCH_USER_PATHS = NO; 522 | CLANG_ANALYZER_NONNULL = YES; 523 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 524 | CLANG_CXX_LIBRARY = "libc++"; 525 | CLANG_ENABLE_MODULES = YES; 526 | CLANG_ENABLE_OBJC_ARC = YES; 527 | CLANG_WARN_BOOL_CONVERSION = YES; 528 | CLANG_WARN_CONSTANT_CONVERSION = YES; 529 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 530 | CLANG_WARN_EMPTY_BODY = YES; 531 | CLANG_WARN_ENUM_CONVERSION = YES; 532 | CLANG_WARN_INT_CONVERSION = YES; 533 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 534 | CLANG_WARN_UNREACHABLE_CODE = YES; 535 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 536 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 537 | COPY_PHASE_STRIP = NO; 538 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 539 | ENABLE_NS_ASSERTIONS = NO; 540 | ENABLE_STRICT_OBJC_MSGSEND = YES; 541 | GCC_C_LANGUAGE_STANDARD = gnu99; 542 | GCC_NO_COMMON_BLOCKS = YES; 543 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 544 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 545 | GCC_WARN_UNDECLARED_SELECTOR = YES; 546 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 547 | GCC_WARN_UNUSED_FUNCTION = YES; 548 | GCC_WARN_UNUSED_VARIABLE = YES; 549 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 550 | MTL_ENABLE_DEBUG_INFO = NO; 551 | SDKROOT = iphoneos; 552 | TARGETED_DEVICE_FAMILY = "1,2"; 553 | VALIDATE_PRODUCT = YES; 554 | }; 555 | name = Release; 556 | }; 557 | 94E850B71D75759C0012027E /* Debug */ = { 558 | isa = XCBuildConfiguration; 559 | baseConfigurationReference = 5CBE8BC6EE4505EA492D9E16 /* Pods-ExtensionsForSafari.debug.xcconfig */; 560 | buildSettings = { 561 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 562 | CODE_SIGN_ENTITLEMENTS = ExtensionsForSafari/ExtensionsForSafari.entitlements; 563 | CODE_SIGN_IDENTITY = "iPhone Developer"; 564 | FRAMEWORK_SEARCH_PATHS = ( 565 | "$(inherited)", 566 | "$(PROJECT_DIR)/Carthage/Build/iOS", 567 | ); 568 | INFOPLIST_FILE = ExtensionsForSafari/Info.plist; 569 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 570 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 571 | PRODUCT_BUNDLE_IDENTIFIER = com.jerrytian.ExtensionsForSafari; 572 | PRODUCT_NAME = "$(TARGET_NAME)"; 573 | }; 574 | name = Debug; 575 | }; 576 | 94E850B81D75759C0012027E /* Release */ = { 577 | isa = XCBuildConfiguration; 578 | baseConfigurationReference = 4D07D1B8708D4E1CA0129F99 /* Pods-ExtensionsForSafari.release.xcconfig */; 579 | buildSettings = { 580 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 581 | CODE_SIGN_ENTITLEMENTS = ExtensionsForSafari/ExtensionsForSafari.entitlements; 582 | CODE_SIGN_IDENTITY = "iPhone Developer"; 583 | FRAMEWORK_SEARCH_PATHS = ( 584 | "$(inherited)", 585 | "$(PROJECT_DIR)/Carthage/Build/iOS", 586 | ); 587 | INFOPLIST_FILE = ExtensionsForSafari/Info.plist; 588 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 589 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 590 | PRODUCT_BUNDLE_IDENTIFIER = com.jerrytian.ExtensionsForSafari; 591 | PRODUCT_NAME = "$(TARGET_NAME)"; 592 | }; 593 | name = Release; 594 | }; 595 | 94E850CA1D7575BE0012027E /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | baseConfigurationReference = CC182BEBBB2FAF996D2E62B2 /* Pods-ExtensionsForSafariAction.debug.xcconfig */; 598 | buildSettings = { 599 | ASSETCATALOG_COMPILER_APPICON_NAME = ActionIcon; 600 | CODE_SIGN_ENTITLEMENTS = ExtensionsForSafariAction/ExtensionsForSafariAction.entitlements; 601 | CODE_SIGN_IDENTITY = "iPhone Developer"; 602 | INFOPLIST_FILE = ExtensionsForSafariAction/Info.plist; 603 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 604 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 605 | PRODUCT_BUNDLE_IDENTIFIER = com.jerrytian.ExtensionsForSafari.Action; 606 | PRODUCT_NAME = "$(TARGET_NAME)"; 607 | SKIP_INSTALL = YES; 608 | }; 609 | name = Debug; 610 | }; 611 | 94E850CB1D7575BE0012027E /* Release */ = { 612 | isa = XCBuildConfiguration; 613 | baseConfigurationReference = 138DD21EB9F47D0C2B736A60 /* Pods-ExtensionsForSafariAction.release.xcconfig */; 614 | buildSettings = { 615 | ASSETCATALOG_COMPILER_APPICON_NAME = ActionIcon; 616 | CODE_SIGN_ENTITLEMENTS = ExtensionsForSafariAction/ExtensionsForSafariAction.entitlements; 617 | CODE_SIGN_IDENTITY = "iPhone Developer"; 618 | INFOPLIST_FILE = ExtensionsForSafariAction/Info.plist; 619 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 620 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 621 | PRODUCT_BUNDLE_IDENTIFIER = com.jerrytian.ExtensionsForSafari.Action; 622 | PRODUCT_NAME = "$(TARGET_NAME)"; 623 | SKIP_INSTALL = YES; 624 | }; 625 | name = Release; 626 | }; 627 | /* End XCBuildConfiguration section */ 628 | 629 | /* Begin XCConfigurationList section */ 630 | 94E8509A1D75759C0012027E /* Build configuration list for PBXProject "ExtensionsForSafari" */ = { 631 | isa = XCConfigurationList; 632 | buildConfigurations = ( 633 | 94E850B41D75759C0012027E /* Debug */, 634 | 94E850B51D75759C0012027E /* Release */, 635 | ); 636 | defaultConfigurationIsVisible = 0; 637 | defaultConfigurationName = Release; 638 | }; 639 | 94E850B61D75759C0012027E /* Build configuration list for PBXNativeTarget "ExtensionsForSafari" */ = { 640 | isa = XCConfigurationList; 641 | buildConfigurations = ( 642 | 94E850B71D75759C0012027E /* Debug */, 643 | 94E850B81D75759C0012027E /* Release */, 644 | ); 645 | defaultConfigurationIsVisible = 0; 646 | defaultConfigurationName = Release; 647 | }; 648 | 94E850C91D7575BE0012027E /* Build configuration list for PBXNativeTarget "ExtensionsForSafariAction" */ = { 649 | isa = XCConfigurationList; 650 | buildConfigurations = ( 651 | 94E850CA1D7575BE0012027E /* Debug */, 652 | 94E850CB1D7575BE0012027E /* Release */, 653 | ); 654 | defaultConfigurationIsVisible = 0; 655 | defaultConfigurationName = Release; 656 | }; 657 | /* End XCConfigurationList section */ 658 | }; 659 | rootObject = 94E850971D75759C0012027E /* Project object */; 660 | } 661 | -------------------------------------------------------------------------------- /ExtensionsForSafari.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExtensionsForSafari.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ExtensionsForSafari/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ExtensionsForSafari/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | // let directory: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("groups.prasanna.appName")! 23 | // let realmPath = directory.path!.stringByAppendingPathComponent("db.realm") 24 | // RLMRealm.setDefaultRealmPath(realmPath) 25 | 26 | RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration]; 27 | configuration.fileURL = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.jerrytian.extensionsforsafari"] URLByAppendingPathComponent:@"db.realm"]; 28 | [RLMRealmConfiguration setDefaultConfiguration:configuration]; 29 | 30 | return YES; 31 | } 32 | 33 | - (void)applicationWillResignActive:(UIApplication *)application { 34 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 35 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 36 | } 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application { 39 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | - (void)applicationWillEnterForeground:(UIApplication *)application { 44 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | - (void)applicationDidBecomeActive:(UIApplication *)application { 48 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 49 | } 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-Small@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-Small@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Spotlight-40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Spotlight-40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-60@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "29x29", 41 | "idiom" : "ipad", 42 | "filename" : "Icon-Small.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "29x29", 47 | "idiom" : "ipad", 48 | "filename" : "Icon-Small@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "40x40", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-Spotlight-40.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "40x40", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-Spotlight-40@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "76x76", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-76.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "76x76", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-76@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "83.5x83.5", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-83.5@2x.png", 79 | "scale" : "2x" 80 | } 81 | ], 82 | "info" : { 83 | "version" : 1, 84 | "author" : "xcode" 85 | }, 86 | "properties" : { 87 | "pre-rendered" : true 88 | } 89 | } -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/ActionIcon.appiconset/Icon-Spotlight-40@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-Small@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-Small@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Spotlight-40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Spotlight-40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-60@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "29x29", 41 | "idiom" : "ipad", 42 | "filename" : "Icon-Small.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "29x29", 47 | "idiom" : "ipad", 48 | "filename" : "Icon-Small@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "40x40", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-Spotlight-40.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "40x40", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-Spotlight-40@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "76x76", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-76.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "76x76", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-76@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "83.5x83.5", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-83.5@2x.png", 79 | "scale" : "2x" 80 | } 81 | ], 82 | "info" : { 83 | "version" : 1, 84 | "author" : "xcode" 85 | } 86 | } -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/ExtensionsForSafari/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/Brand Assets.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "ipad", 6 | "minimum-system-version" : "7.0", 7 | "extent" : "full-screen", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "landscape", 12 | "idiom" : "ipad", 13 | "minimum-system-version" : "7.0", 14 | "extent" : "full-screen", 15 | "scale" : "1x" 16 | }, 17 | { 18 | "orientation" : "landscape", 19 | "idiom" : "ipad", 20 | "minimum-system-version" : "7.0", 21 | "extent" : "full-screen", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "orientation" : "portrait", 26 | "idiom" : "iphone", 27 | "minimum-system-version" : "7.0", 28 | "scale" : "2x" 29 | }, 30 | { 31 | "orientation" : "portrait", 32 | "idiom" : "iphone", 33 | "minimum-system-version" : "7.0", 34 | "subtype" : "retina4", 35 | "scale" : "2x" 36 | }, 37 | { 38 | "orientation" : "portrait", 39 | "idiom" : "ipad", 40 | "minimum-system-version" : "7.0", 41 | "extent" : "full-screen", 42 | "scale" : "1x" 43 | } 44 | ], 45 | "info" : { 46 | "version" : 1, 47 | "author" : "xcode" 48 | } 49 | } -------------------------------------------------------------------------------- /ExtensionsForSafari/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ExtensionsForSafari/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ExtensionsForSafari/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/html/sublime.html: -------------------------------------------------------------------------------- 1 | 2 | Editor 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 21 | 22 | 23 | 25 | 26 | 27 | 53 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/lib/codemirror.css: -------------------------------------------------------------------------------- 1 | /* BASICS */ 2 | 3 | .CodeMirror { 4 | /* Set height, width, borders, and global font properties here */ 5 | font-family: monospace; 6 | height: 300px; 7 | color: black; 8 | } 9 | 10 | /* PADDING */ 11 | 12 | .CodeMirror-lines { 13 | padding: 4px 0; /* Vertical padding around content */ 14 | } 15 | .CodeMirror pre { 16 | padding: 0 4px; /* Horizontal padding of content */ 17 | } 18 | 19 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 20 | background-color: white; /* The little square between H and V scrollbars */ 21 | } 22 | 23 | /* GUTTER */ 24 | 25 | .CodeMirror-gutters { 26 | border-right: 1px solid #ddd; 27 | background-color: #f7f7f7; 28 | white-space: nowrap; 29 | } 30 | .CodeMirror-linenumbers {} 31 | .CodeMirror-linenumber { 32 | padding: 0 3px 0 5px; 33 | min-width: 20px; 34 | text-align: right; 35 | color: #999; 36 | white-space: nowrap; 37 | } 38 | 39 | .CodeMirror-guttermarker { color: black; } 40 | .CodeMirror-guttermarker-subtle { color: #999; } 41 | 42 | /* CURSOR */ 43 | 44 | .CodeMirror-cursor { 45 | border-left: 1px solid black; 46 | border-right: none; 47 | width: 0; 48 | } 49 | /* Shown when moving in bi-directional text */ 50 | .CodeMirror div.CodeMirror-secondarycursor { 51 | border-left: 1px solid silver; 52 | } 53 | .cm-fat-cursor .CodeMirror-cursor { 54 | width: auto; 55 | border: 0 !important; 56 | background: #7e7; 57 | } 58 | .cm-fat-cursor div.CodeMirror-cursors { 59 | z-index: 1; 60 | } 61 | 62 | .cm-animate-fat-cursor { 63 | width: auto; 64 | border: 0; 65 | -webkit-animation: blink 1.06s steps(1) infinite; 66 | -moz-animation: blink 1.06s steps(1) infinite; 67 | animation: blink 1.06s steps(1) infinite; 68 | background-color: #7e7; 69 | } 70 | @-moz-keyframes blink { 71 | 0% {} 72 | 50% { background-color: transparent; } 73 | 100% {} 74 | } 75 | @-webkit-keyframes blink { 76 | 0% {} 77 | 50% { background-color: transparent; } 78 | 100% {} 79 | } 80 | @keyframes blink { 81 | 0% {} 82 | 50% { background-color: transparent; } 83 | 100% {} 84 | } 85 | 86 | /* Can style cursor different in overwrite (non-insert) mode */ 87 | .CodeMirror-overwrite .CodeMirror-cursor {} 88 | 89 | .cm-tab { display: inline-block; text-decoration: inherit; } 90 | 91 | .CodeMirror-rulers { 92 | position: absolute; 93 | left: 0; right: 0; top: -50px; bottom: -20px; 94 | overflow: hidden; 95 | } 96 | .CodeMirror-ruler { 97 | border-left: 1px solid #ccc; 98 | top: 0; bottom: 0; 99 | position: absolute; 100 | } 101 | 102 | /* DEFAULT THEME */ 103 | 104 | .cm-s-default .cm-header {color: blue;} 105 | .cm-s-default .cm-quote {color: #090;} 106 | .cm-negative {color: #d44;} 107 | .cm-positive {color: #292;} 108 | .cm-header, .cm-strong {font-weight: bold;} 109 | .cm-em {font-style: italic;} 110 | .cm-link {text-decoration: underline;} 111 | .cm-strikethrough {text-decoration: line-through;} 112 | 113 | .cm-s-default .cm-keyword {color: #708;} 114 | .cm-s-default .cm-atom {color: #219;} 115 | .cm-s-default .cm-number {color: #164;} 116 | .cm-s-default .cm-def {color: #00f;} 117 | .cm-s-default .cm-variable, 118 | .cm-s-default .cm-punctuation, 119 | .cm-s-default .cm-property, 120 | .cm-s-default .cm-operator {} 121 | .cm-s-default .cm-variable-2 {color: #05a;} 122 | .cm-s-default .cm-variable-3 {color: #085;} 123 | .cm-s-default .cm-comment {color: #a50;} 124 | .cm-s-default .cm-string {color: #a11;} 125 | .cm-s-default .cm-string-2 {color: #f50;} 126 | .cm-s-default .cm-meta {color: #555;} 127 | .cm-s-default .cm-qualifier {color: #555;} 128 | .cm-s-default .cm-builtin {color: #30a;} 129 | .cm-s-default .cm-bracket {color: #997;} 130 | .cm-s-default .cm-tag {color: #170;} 131 | .cm-s-default .cm-attribute {color: #00c;} 132 | .cm-s-default .cm-hr {color: #999;} 133 | .cm-s-default .cm-link {color: #00c;} 134 | 135 | .cm-s-default .cm-error {color: #f00;} 136 | .cm-invalidchar {color: #f00;} 137 | 138 | .CodeMirror-composing { border-bottom: 2px solid; } 139 | 140 | /* Default styles for common addons */ 141 | 142 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} 143 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} 144 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } 145 | .CodeMirror-activeline-background {background: #e8f2ff;} 146 | 147 | /* STOP */ 148 | 149 | /* The rest of this file contains styles related to the mechanics of 150 | the editor. You probably shouldn't touch them. */ 151 | 152 | .CodeMirror { 153 | position: relative; 154 | overflow: hidden; 155 | background: white; 156 | } 157 | 158 | .CodeMirror-scroll { 159 | overflow: scroll !important; /* Things will break if this is overridden */ 160 | /* 30px is the magic margin used to hide the element's real scrollbars */ 161 | /* See overflow: hidden in .CodeMirror */ 162 | margin-bottom: -30px; margin-right: -30px; 163 | padding-bottom: 30px; 164 | height: 100%; 165 | outline: none; /* Prevent dragging from highlighting the element */ 166 | position: relative; 167 | } 168 | .CodeMirror-sizer { 169 | position: relative; 170 | border-right: 30px solid transparent; 171 | } 172 | 173 | /* The fake, visible scrollbars. Used to force redraw during scrolling 174 | before actual scrolling happens, thus preventing shaking and 175 | flickering artifacts. */ 176 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 177 | position: absolute; 178 | z-index: 6; 179 | display: none; 180 | } 181 | .CodeMirror-vscrollbar { 182 | right: 0; top: 0; 183 | overflow-x: hidden; 184 | overflow-y: scroll; 185 | } 186 | .CodeMirror-hscrollbar { 187 | bottom: 0; left: 0; 188 | overflow-y: hidden; 189 | overflow-x: scroll; 190 | } 191 | .CodeMirror-scrollbar-filler { 192 | right: 0; bottom: 0; 193 | } 194 | .CodeMirror-gutter-filler { 195 | left: 0; bottom: 0; 196 | } 197 | 198 | .CodeMirror-gutters { 199 | position: absolute; left: 0; top: 0; 200 | min-height: 100%; 201 | z-index: 3; 202 | } 203 | .CodeMirror-gutter { 204 | white-space: normal; 205 | height: 100%; 206 | display: inline-block; 207 | vertical-align: top; 208 | margin-bottom: -30px; 209 | /* Hack to make IE7 behave */ 210 | *zoom:1; 211 | *display:inline; 212 | } 213 | .CodeMirror-gutter-wrapper { 214 | position: absolute; 215 | z-index: 4; 216 | background: none !important; 217 | border: none !important; 218 | } 219 | .CodeMirror-gutter-background { 220 | position: absolute; 221 | top: 0; bottom: 0; 222 | z-index: 4; 223 | } 224 | .CodeMirror-gutter-elt { 225 | position: absolute; 226 | cursor: default; 227 | z-index: 4; 228 | } 229 | .CodeMirror-gutter-wrapper { 230 | -webkit-user-select: none; 231 | -moz-user-select: none; 232 | user-select: none; 233 | } 234 | 235 | .CodeMirror-lines { 236 | cursor: text; 237 | min-height: 1px; /* prevents collapsing before first draw */ 238 | } 239 | .CodeMirror pre { 240 | /* Reset some styles that the rest of the page might have set */ 241 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; 242 | border-width: 0; 243 | background: transparent; 244 | font-family: inherit; 245 | font-size: inherit; 246 | margin: 0; 247 | white-space: pre; 248 | word-wrap: normal; 249 | line-height: inherit; 250 | color: inherit; 251 | z-index: 2; 252 | position: relative; 253 | overflow: visible; 254 | -webkit-tap-highlight-color: transparent; 255 | -webkit-font-variant-ligatures: none; 256 | font-variant-ligatures: none; 257 | } 258 | .CodeMirror-wrap pre { 259 | word-wrap: break-word; 260 | white-space: pre-wrap; 261 | word-break: normal; 262 | } 263 | 264 | .CodeMirror-linebackground { 265 | position: absolute; 266 | left: 0; right: 0; top: 0; bottom: 0; 267 | z-index: 0; 268 | } 269 | 270 | .CodeMirror-linewidget { 271 | position: relative; 272 | z-index: 2; 273 | overflow: auto; 274 | } 275 | 276 | .CodeMirror-widget {} 277 | 278 | .CodeMirror-code { 279 | outline: none; 280 | } 281 | 282 | /* Force content-box sizing for the elements where we expect it */ 283 | .CodeMirror-scroll, 284 | .CodeMirror-sizer, 285 | .CodeMirror-gutter, 286 | .CodeMirror-gutters, 287 | .CodeMirror-linenumber { 288 | -moz-box-sizing: content-box; 289 | box-sizing: content-box; 290 | } 291 | 292 | .CodeMirror-measure { 293 | position: absolute; 294 | width: 100%; 295 | height: 0; 296 | overflow: hidden; 297 | visibility: hidden; 298 | } 299 | 300 | .CodeMirror-cursor { 301 | position: absolute; 302 | pointer-events: none; 303 | } 304 | .CodeMirror-measure pre { position: static; } 305 | 306 | div.CodeMirror-cursors { 307 | visibility: hidden; 308 | position: relative; 309 | z-index: 3; 310 | } 311 | div.CodeMirror-dragcursors { 312 | visibility: visible; 313 | } 314 | 315 | .CodeMirror-focused div.CodeMirror-cursors { 316 | visibility: visible; 317 | } 318 | 319 | .CodeMirror-selected { background: #d9d9d9; } 320 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } 321 | .CodeMirror-crosshair { cursor: crosshair; } 322 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } 323 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } 324 | 325 | .cm-searching { 326 | background: #ffa; 327 | background: rgba(255, 255, 0, .4); 328 | } 329 | 330 | /* IE7 hack to prevent it from returning funny offsetTops on the spans */ 331 | .CodeMirror span { *vertical-align: text-bottom; } 332 | 333 | /* Used to force a border model for a node */ 334 | .cm-force-border { padding-right: .1px; } 335 | 336 | @media print { 337 | /* Hide the cursor when printing */ 338 | .CodeMirror div.CodeMirror-cursors { 339 | visibility: hidden; 340 | } 341 | } 342 | 343 | /* See issue #2901 */ 344 | .cm-tab-wrap-hack:after { content: ''; } 345 | 346 | /* Help users use markselection to safely style text background */ 347 | span.CodeMirror-selectedtext { background: none; } 348 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/mode/javascript/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: JavaScript mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 27 | 28 |
29 |

JavaScript mode

30 | 31 | 32 |
81 | 82 | 90 | 91 |

92 | JavaScript mode supports several configuration options: 93 |

    94 |
  • json which will set the mode to expect JSON 95 | data rather than a JavaScript program.
  • 96 |
  • jsonld which will set the mode to expect 97 | JSON-LD linked data rather 98 | than a JavaScript program (demo).
  • 99 |
  • typescript which will activate additional 100 | syntax highlighting and some other things for TypeScript code 101 | (demo).
  • 102 |
  • statementIndent which (given a number) will 103 | determine the amount of indentation to use for statements 104 | continued on a new line.
  • 105 |
  • wordCharacters, a regexp that indicates which 106 | characters should be considered part of an identifier. 107 | Defaults to /[\w$]/, which does not handle 108 | non-ASCII identifiers. Can be set to something more elaborate 109 | to improve Unicode support.
  • 110 |
111 |

112 | 113 |

MIME types defined: text/javascript, application/json, application/ld+json, text/typescript, application/typescript.

114 |
115 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/mode/javascript/javascript.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function expressionAllowed(stream, state, backUp) { 15 | return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) || 16 | (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) 17 | } 18 | 19 | CodeMirror.defineMode("javascript", function(config, parserConfig) { 20 | var indentUnit = config.indentUnit; 21 | var statementIndent = parserConfig.statementIndent; 22 | var jsonldMode = parserConfig.jsonld; 23 | var jsonMode = parserConfig.json || jsonldMode; 24 | var isTS = parserConfig.typescript; 25 | var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; 26 | 27 | // Tokenizer 28 | 29 | var keywords = function(){ 30 | function kw(type) {return {type: type, style: "keyword"};} 31 | var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); 32 | var operator = kw("operator"), atom = {type: "atom", style: "atom"}; 33 | 34 | var jsKeywords = { 35 | "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, 36 | "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, 37 | "var": kw("var"), "const": kw("var"), "let": kw("var"), 38 | "function": kw("function"), "catch": kw("catch"), 39 | "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), 40 | "in": operator, "typeof": operator, "instanceof": operator, 41 | "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 42 | "this": kw("this"), "class": kw("class"), "super": kw("atom"), 43 | "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, 44 | "await": C, "async": kw("async") 45 | }; 46 | 47 | // Extend the 'normal' keywords with the TypeScript language extensions 48 | if (isTS) { 49 | var type = {type: "variable", style: "variable-3"}; 50 | var tsKeywords = { 51 | // object-like things 52 | "interface": kw("class"), 53 | "implements": C, 54 | "namespace": C, 55 | "module": kw("module"), 56 | "enum": kw("module"), 57 | 58 | // scope modifiers 59 | "public": kw("modifier"), 60 | "private": kw("modifier"), 61 | "protected": kw("modifier"), 62 | "abstract": kw("modifier"), 63 | 64 | // operators 65 | "as": operator, 66 | 67 | // types 68 | "string": type, "number": type, "boolean": type, "any": type 69 | }; 70 | 71 | for (var attr in tsKeywords) { 72 | jsKeywords[attr] = tsKeywords[attr]; 73 | } 74 | } 75 | 76 | return jsKeywords; 77 | }(); 78 | 79 | var isOperatorChar = /[+\-*&%=<>!?|~^]/; 80 | var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; 81 | 82 | function readRegexp(stream) { 83 | var escaped = false, next, inSet = false; 84 | while ((next = stream.next()) != null) { 85 | if (!escaped) { 86 | if (next == "/" && !inSet) return; 87 | if (next == "[") inSet = true; 88 | else if (inSet && next == "]") inSet = false; 89 | } 90 | escaped = !escaped && next == "\\"; 91 | } 92 | } 93 | 94 | // Used as scratch variables to communicate multiple values without 95 | // consing up tons of objects. 96 | var type, content; 97 | function ret(tp, style, cont) { 98 | type = tp; content = cont; 99 | return style; 100 | } 101 | function tokenBase(stream, state) { 102 | var ch = stream.next(); 103 | if (ch == '"' || ch == "'") { 104 | state.tokenize = tokenString(ch); 105 | return state.tokenize(stream, state); 106 | } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { 107 | return ret("number", "number"); 108 | } else if (ch == "." && stream.match("..")) { 109 | return ret("spread", "meta"); 110 | } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 111 | return ret(ch); 112 | } else if (ch == "=" && stream.eat(">")) { 113 | return ret("=>", "operator"); 114 | } else if (ch == "0" && stream.eat(/x/i)) { 115 | stream.eatWhile(/[\da-f]/i); 116 | return ret("number", "number"); 117 | } else if (ch == "0" && stream.eat(/o/i)) { 118 | stream.eatWhile(/[0-7]/i); 119 | return ret("number", "number"); 120 | } else if (ch == "0" && stream.eat(/b/i)) { 121 | stream.eatWhile(/[01]/i); 122 | return ret("number", "number"); 123 | } else if (/\d/.test(ch)) { 124 | stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); 125 | return ret("number", "number"); 126 | } else if (ch == "/") { 127 | if (stream.eat("*")) { 128 | state.tokenize = tokenComment; 129 | return tokenComment(stream, state); 130 | } else if (stream.eat("/")) { 131 | stream.skipToEnd(); 132 | return ret("comment", "comment"); 133 | } else if (expressionAllowed(stream, state, 1)) { 134 | readRegexp(stream); 135 | stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); 136 | return ret("regexp", "string-2"); 137 | } else { 138 | stream.eatWhile(isOperatorChar); 139 | return ret("operator", "operator", stream.current()); 140 | } 141 | } else if (ch == "`") { 142 | state.tokenize = tokenQuasi; 143 | return tokenQuasi(stream, state); 144 | } else if (ch == "#") { 145 | stream.skipToEnd(); 146 | return ret("error", "error"); 147 | } else if (isOperatorChar.test(ch)) { 148 | stream.eatWhile(isOperatorChar); 149 | return ret("operator", "operator", stream.current()); 150 | } else if (wordRE.test(ch)) { 151 | stream.eatWhile(wordRE); 152 | var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; 153 | return (known && state.lastType != ".") ? ret(known.type, known.style, word) : 154 | ret("variable", "variable", word); 155 | } 156 | } 157 | 158 | function tokenString(quote) { 159 | return function(stream, state) { 160 | var escaped = false, next; 161 | if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ 162 | state.tokenize = tokenBase; 163 | return ret("jsonld-keyword", "meta"); 164 | } 165 | while ((next = stream.next()) != null) { 166 | if (next == quote && !escaped) break; 167 | escaped = !escaped && next == "\\"; 168 | } 169 | if (!escaped) state.tokenize = tokenBase; 170 | return ret("string", "string"); 171 | }; 172 | } 173 | 174 | function tokenComment(stream, state) { 175 | var maybeEnd = false, ch; 176 | while (ch = stream.next()) { 177 | if (ch == "/" && maybeEnd) { 178 | state.tokenize = tokenBase; 179 | break; 180 | } 181 | maybeEnd = (ch == "*"); 182 | } 183 | return ret("comment", "comment"); 184 | } 185 | 186 | function tokenQuasi(stream, state) { 187 | var escaped = false, next; 188 | while ((next = stream.next()) != null) { 189 | if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { 190 | state.tokenize = tokenBase; 191 | break; 192 | } 193 | escaped = !escaped && next == "\\"; 194 | } 195 | return ret("quasi", "string-2", stream.current()); 196 | } 197 | 198 | var brackets = "([{}])"; 199 | // This is a crude lookahead trick to try and notice that we're 200 | // parsing the argument patterns for a fat-arrow function before we 201 | // actually hit the arrow token. It only works if the arrow is on 202 | // the same line as the arguments and there's no strange noise 203 | // (comments) in between. Fallback is to only notice when we hit the 204 | // arrow, and not declare the arguments as locals for the arrow 205 | // body. 206 | function findFatArrow(stream, state) { 207 | if (state.fatArrowAt) state.fatArrowAt = null; 208 | var arrow = stream.string.indexOf("=>", stream.start); 209 | if (arrow < 0) return; 210 | 211 | var depth = 0, sawSomething = false; 212 | for (var pos = arrow - 1; pos >= 0; --pos) { 213 | var ch = stream.string.charAt(pos); 214 | var bracket = brackets.indexOf(ch); 215 | if (bracket >= 0 && bracket < 3) { 216 | if (!depth) { ++pos; break; } 217 | if (--depth == 0) { if (ch == "(") sawSomething = true; break; } 218 | } else if (bracket >= 3 && bracket < 6) { 219 | ++depth; 220 | } else if (wordRE.test(ch)) { 221 | sawSomething = true; 222 | } else if (/["'\/]/.test(ch)) { 223 | return; 224 | } else if (sawSomething && !depth) { 225 | ++pos; 226 | break; 227 | } 228 | } 229 | if (sawSomething && !depth) state.fatArrowAt = pos; 230 | } 231 | 232 | // Parser 233 | 234 | var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; 235 | 236 | function JSLexical(indented, column, type, align, prev, info) { 237 | this.indented = indented; 238 | this.column = column; 239 | this.type = type; 240 | this.prev = prev; 241 | this.info = info; 242 | if (align != null) this.align = align; 243 | } 244 | 245 | function inScope(state, varname) { 246 | for (var v = state.localVars; v; v = v.next) 247 | if (v.name == varname) return true; 248 | for (var cx = state.context; cx; cx = cx.prev) { 249 | for (var v = cx.vars; v; v = v.next) 250 | if (v.name == varname) return true; 251 | } 252 | } 253 | 254 | function parseJS(state, style, type, content, stream) { 255 | var cc = state.cc; 256 | // Communicate our context to the combinators. 257 | // (Less wasteful than consing up a hundred closures on every call.) 258 | cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; 259 | 260 | if (!state.lexical.hasOwnProperty("align")) 261 | state.lexical.align = true; 262 | 263 | while(true) { 264 | var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; 265 | if (combinator(type, content)) { 266 | while(cc.length && cc[cc.length - 1].lex) 267 | cc.pop()(); 268 | if (cx.marked) return cx.marked; 269 | if (type == "variable" && inScope(state, content)) return "variable-2"; 270 | return style; 271 | } 272 | } 273 | } 274 | 275 | // Combinator utils 276 | 277 | var cx = {state: null, column: null, marked: null, cc: null}; 278 | function pass() { 279 | for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); 280 | } 281 | function cont() { 282 | pass.apply(null, arguments); 283 | return true; 284 | } 285 | function register(varname) { 286 | function inList(list) { 287 | for (var v = list; v; v = v.next) 288 | if (v.name == varname) return true; 289 | return false; 290 | } 291 | var state = cx.state; 292 | cx.marked = "def"; 293 | if (state.context) { 294 | if (inList(state.localVars)) return; 295 | state.localVars = {name: varname, next: state.localVars}; 296 | } else { 297 | if (inList(state.globalVars)) return; 298 | if (parserConfig.globalVars) 299 | state.globalVars = {name: varname, next: state.globalVars}; 300 | } 301 | } 302 | 303 | // Combinators 304 | 305 | var defaultVars = {name: "this", next: {name: "arguments"}}; 306 | function pushcontext() { 307 | cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; 308 | cx.state.localVars = defaultVars; 309 | } 310 | function popcontext() { 311 | cx.state.localVars = cx.state.context.vars; 312 | cx.state.context = cx.state.context.prev; 313 | } 314 | function pushlex(type, info) { 315 | var result = function() { 316 | var state = cx.state, indent = state.indented; 317 | if (state.lexical.type == "stat") indent = state.lexical.indented; 318 | else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) 319 | indent = outer.indented; 320 | state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); 321 | }; 322 | result.lex = true; 323 | return result; 324 | } 325 | function poplex() { 326 | var state = cx.state; 327 | if (state.lexical.prev) { 328 | if (state.lexical.type == ")") 329 | state.indented = state.lexical.indented; 330 | state.lexical = state.lexical.prev; 331 | } 332 | } 333 | poplex.lex = true; 334 | 335 | function expect(wanted) { 336 | function exp(type) { 337 | if (type == wanted) return cont(); 338 | else if (wanted == ";") return pass(); 339 | else return cont(exp); 340 | }; 341 | return exp; 342 | } 343 | 344 | function statement(type, value) { 345 | if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); 346 | if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); 347 | if (type == "keyword b") return cont(pushlex("form"), statement, poplex); 348 | if (type == "{") return cont(pushlex("}"), block, poplex); 349 | if (type == ";") return cont(); 350 | if (type == "if") { 351 | if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) 352 | cx.state.cc.pop()(); 353 | return cont(pushlex("form"), expression, statement, poplex, maybeelse); 354 | } 355 | if (type == "function") return cont(functiondef); 356 | if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); 357 | if (type == "variable") return cont(pushlex("stat"), maybelabel); 358 | if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), 359 | block, poplex, poplex); 360 | if (type == "case") return cont(expression, expect(":")); 361 | if (type == "default") return cont(expect(":")); 362 | if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 363 | statement, poplex, popcontext); 364 | if (type == "class") return cont(pushlex("form"), className, poplex); 365 | if (type == "export") return cont(pushlex("stat"), afterExport, poplex); 366 | if (type == "import") return cont(pushlex("stat"), afterImport, poplex); 367 | if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) 368 | if (type == "async") return cont(statement) 369 | return pass(pushlex("stat"), expression, expect(";"), poplex); 370 | } 371 | function expression(type) { 372 | return expressionInner(type, false); 373 | } 374 | function expressionNoComma(type) { 375 | return expressionInner(type, true); 376 | } 377 | function expressionInner(type, noComma) { 378 | if (cx.state.fatArrowAt == cx.stream.start) { 379 | var body = noComma ? arrowBodyNoComma : arrowBody; 380 | if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); 381 | else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); 382 | } 383 | 384 | var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; 385 | if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 386 | if (type == "function") return cont(functiondef, maybeop); 387 | if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression); 388 | if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); 389 | if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); 390 | if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); 391 | if (type == "{") return contCommasep(objprop, "}", null, maybeop); 392 | if (type == "quasi") return pass(quasi, maybeop); 393 | if (type == "new") return cont(maybeTarget(noComma)); 394 | return cont(); 395 | } 396 | function maybeexpression(type) { 397 | if (type.match(/[;\}\)\],]/)) return pass(); 398 | return pass(expression); 399 | } 400 | function maybeexpressionNoComma(type) { 401 | if (type.match(/[;\}\)\],]/)) return pass(); 402 | return pass(expressionNoComma); 403 | } 404 | 405 | function maybeoperatorComma(type, value) { 406 | if (type == ",") return cont(expression); 407 | return maybeoperatorNoComma(type, value, false); 408 | } 409 | function maybeoperatorNoComma(type, value, noComma) { 410 | var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 411 | var expr = noComma == false ? expression : expressionNoComma; 412 | if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); 413 | if (type == "operator") { 414 | if (/\+\+|--/.test(value)) return cont(me); 415 | if (value == "?") return cont(expression, expect(":"), expr); 416 | return cont(expr); 417 | } 418 | if (type == "quasi") { return pass(quasi, me); } 419 | if (type == ";") return; 420 | if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); 421 | if (type == ".") return cont(property, me); 422 | if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); 423 | } 424 | function quasi(type, value) { 425 | if (type != "quasi") return pass(); 426 | if (value.slice(value.length - 2) != "${") return cont(quasi); 427 | return cont(expression, continueQuasi); 428 | } 429 | function continueQuasi(type) { 430 | if (type == "}") { 431 | cx.marked = "string-2"; 432 | cx.state.tokenize = tokenQuasi; 433 | return cont(quasi); 434 | } 435 | } 436 | function arrowBody(type) { 437 | findFatArrow(cx.stream, cx.state); 438 | return pass(type == "{" ? statement : expression); 439 | } 440 | function arrowBodyNoComma(type) { 441 | findFatArrow(cx.stream, cx.state); 442 | return pass(type == "{" ? statement : expressionNoComma); 443 | } 444 | function maybeTarget(noComma) { 445 | return function(type) { 446 | if (type == ".") return cont(noComma ? targetNoComma : target); 447 | else return pass(noComma ? expressionNoComma : expression); 448 | }; 449 | } 450 | function target(_, value) { 451 | if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } 452 | } 453 | function targetNoComma(_, value) { 454 | if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } 455 | } 456 | function maybelabel(type) { 457 | if (type == ":") return cont(poplex, statement); 458 | return pass(maybeoperatorComma, expect(";"), poplex); 459 | } 460 | function property(type) { 461 | if (type == "variable") {cx.marked = "property"; return cont();} 462 | } 463 | function objprop(type, value) { 464 | if (type == "async") { 465 | cx.marked = "property"; 466 | return cont(objprop); 467 | } else if (type == "variable" || cx.style == "keyword") { 468 | cx.marked = "property"; 469 | if (value == "get" || value == "set") return cont(getterSetter); 470 | return cont(afterprop); 471 | } else if (type == "number" || type == "string") { 472 | cx.marked = jsonldMode ? "property" : (cx.style + " property"); 473 | return cont(afterprop); 474 | } else if (type == "jsonld-keyword") { 475 | return cont(afterprop); 476 | } else if (type == "modifier") { 477 | return cont(objprop) 478 | } else if (type == "[") { 479 | return cont(expression, expect("]"), afterprop); 480 | } else if (type == "spread") { 481 | return cont(expression); 482 | } else if (type == ":") { 483 | return pass(afterprop) 484 | } 485 | } 486 | function getterSetter(type) { 487 | if (type != "variable") return pass(afterprop); 488 | cx.marked = "property"; 489 | return cont(functiondef); 490 | } 491 | function afterprop(type) { 492 | if (type == ":") return cont(expressionNoComma); 493 | if (type == "(") return pass(functiondef); 494 | } 495 | function commasep(what, end) { 496 | function proceed(type, value) { 497 | if (type == ",") { 498 | var lex = cx.state.lexical; 499 | if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; 500 | return cont(function(type, value) { 501 | if (type == end || value == end) return pass() 502 | return pass(what) 503 | }, proceed); 504 | } 505 | if (type == end || value == end) return cont(); 506 | return cont(expect(end)); 507 | } 508 | return function(type, value) { 509 | if (type == end || value == end) return cont(); 510 | return pass(what, proceed); 511 | }; 512 | } 513 | function contCommasep(what, end, info) { 514 | for (var i = 3; i < arguments.length; i++) 515 | cx.cc.push(arguments[i]); 516 | return cont(pushlex(end, info), commasep(what, end), poplex); 517 | } 518 | function block(type) { 519 | if (type == "}") return cont(); 520 | return pass(statement, block); 521 | } 522 | function maybetype(type) { 523 | if (isTS && type == ":") return cont(typeexpr); 524 | } 525 | function maybedefault(_, value) { 526 | if (value == "=") return cont(expressionNoComma); 527 | } 528 | function typeexpr(type) { 529 | if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);} 530 | if (type == "{") return cont(commasep(typeprop, "}")) 531 | if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) 532 | } 533 | function maybeReturnType(type) { 534 | if (type == "=>") return cont(typeexpr) 535 | } 536 | function typeprop(type) { 537 | if (type == "variable" || cx.style == "keyword") { 538 | cx.marked = "property" 539 | return cont(typeprop) 540 | } else if (type == ":") { 541 | return cont(typeexpr) 542 | } 543 | } 544 | function typearg(type) { 545 | if (type == "variable") return cont(typearg) 546 | else if (type == ":") return cont(typeexpr) 547 | } 548 | function afterType(type, value) { 549 | if (value == "<") return cont(commasep(typeexpr, ">"), afterType) 550 | if (type == "[") return cont(expect("]"), afterType) 551 | } 552 | function vardef() { 553 | return pass(pattern, maybetype, maybeAssign, vardefCont); 554 | } 555 | function pattern(type, value) { 556 | if (type == "modifier") return cont(pattern) 557 | if (type == "variable") { register(value); return cont(); } 558 | if (type == "spread") return cont(pattern); 559 | if (type == "[") return contCommasep(pattern, "]"); 560 | if (type == "{") return contCommasep(proppattern, "}"); 561 | } 562 | function proppattern(type, value) { 563 | if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { 564 | register(value); 565 | return cont(maybeAssign); 566 | } 567 | if (type == "variable") cx.marked = "property"; 568 | if (type == "spread") return cont(pattern); 569 | if (type == "}") return pass(); 570 | return cont(expect(":"), pattern, maybeAssign); 571 | } 572 | function maybeAssign(_type, value) { 573 | if (value == "=") return cont(expressionNoComma); 574 | } 575 | function vardefCont(type) { 576 | if (type == ",") return cont(vardef); 577 | } 578 | function maybeelse(type, value) { 579 | if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); 580 | } 581 | function forspec(type) { 582 | if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); 583 | } 584 | function forspec1(type) { 585 | if (type == "var") return cont(vardef, expect(";"), forspec2); 586 | if (type == ";") return cont(forspec2); 587 | if (type == "variable") return cont(formaybeinof); 588 | return pass(expression, expect(";"), forspec2); 589 | } 590 | function formaybeinof(_type, value) { 591 | if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 592 | return cont(maybeoperatorComma, forspec2); 593 | } 594 | function forspec2(type, value) { 595 | if (type == ";") return cont(forspec3); 596 | if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 597 | return pass(expression, expect(";"), forspec3); 598 | } 599 | function forspec3(type) { 600 | if (type != ")") cont(expression); 601 | } 602 | function functiondef(type, value) { 603 | if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} 604 | if (type == "variable") {register(value); return cont(functiondef);} 605 | if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); 606 | } 607 | function funarg(type) { 608 | if (type == "spread") return cont(funarg); 609 | return pass(pattern, maybetype, maybedefault); 610 | } 611 | function className(type, value) { 612 | if (type == "variable") {register(value); return cont(classNameAfter);} 613 | } 614 | function classNameAfter(type, value) { 615 | if (value == "extends") return cont(isTS ? typeexpr : expression, classNameAfter); 616 | if (type == "{") return cont(pushlex("}"), classBody, poplex); 617 | } 618 | function classBody(type, value) { 619 | if (type == "variable" || cx.style == "keyword") { 620 | if (value == "static") { 621 | cx.marked = "keyword"; 622 | return cont(classBody); 623 | } 624 | cx.marked = "property"; 625 | if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); 626 | return cont(functiondef, classBody); 627 | } 628 | if (value == "*") { 629 | cx.marked = "keyword"; 630 | return cont(classBody); 631 | } 632 | if (type == ";") return cont(classBody); 633 | if (type == "}") return cont(); 634 | } 635 | function classGetterSetter(type) { 636 | if (type != "variable") return pass(); 637 | cx.marked = "property"; 638 | return cont(); 639 | } 640 | function afterExport(_type, value) { 641 | if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } 642 | if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } 643 | return pass(statement); 644 | } 645 | function afterImport(type) { 646 | if (type == "string") return cont(); 647 | return pass(importSpec, maybeFrom); 648 | } 649 | function importSpec(type, value) { 650 | if (type == "{") return contCommasep(importSpec, "}"); 651 | if (type == "variable") register(value); 652 | if (value == "*") cx.marked = "keyword"; 653 | return cont(maybeAs); 654 | } 655 | function maybeAs(_type, value) { 656 | if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } 657 | } 658 | function maybeFrom(_type, value) { 659 | if (value == "from") { cx.marked = "keyword"; return cont(expression); } 660 | } 661 | function arrayLiteral(type) { 662 | if (type == "]") return cont(); 663 | return pass(commasep(expressionNoComma, "]")); 664 | } 665 | 666 | function isContinuedStatement(state, textAfter) { 667 | return state.lastType == "operator" || state.lastType == "," || 668 | isOperatorChar.test(textAfter.charAt(0)) || 669 | /[,.]/.test(textAfter.charAt(0)); 670 | } 671 | 672 | // Interface 673 | 674 | return { 675 | startState: function(basecolumn) { 676 | var state = { 677 | tokenize: tokenBase, 678 | lastType: "sof", 679 | cc: [], 680 | lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), 681 | localVars: parserConfig.localVars, 682 | context: parserConfig.localVars && {vars: parserConfig.localVars}, 683 | indented: basecolumn || 0 684 | }; 685 | if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") 686 | state.globalVars = parserConfig.globalVars; 687 | return state; 688 | }, 689 | 690 | token: function(stream, state) { 691 | if (stream.sol()) { 692 | if (!state.lexical.hasOwnProperty("align")) 693 | state.lexical.align = false; 694 | state.indented = stream.indentation(); 695 | findFatArrow(stream, state); 696 | } 697 | if (state.tokenize != tokenComment && stream.eatSpace()) return null; 698 | var style = state.tokenize(stream, state); 699 | if (type == "comment") return style; 700 | state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; 701 | return parseJS(state, style, type, content, stream); 702 | }, 703 | 704 | indent: function(state, textAfter) { 705 | if (state.tokenize == tokenComment) return CodeMirror.Pass; 706 | if (state.tokenize != tokenBase) return 0; 707 | var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; 708 | // Kludge to prevent 'maybelse' from blocking lexical scope pops 709 | if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { 710 | var c = state.cc[i]; 711 | if (c == poplex) lexical = lexical.prev; 712 | else if (c != maybeelse) break; 713 | } 714 | if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; 715 | if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") 716 | lexical = lexical.prev; 717 | var type = lexical.type, closing = firstChar == type; 718 | 719 | if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); 720 | else if (type == "form" && firstChar == "{") return lexical.indented; 721 | else if (type == "form") return lexical.indented + indentUnit; 722 | else if (type == "stat") 723 | return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); 724 | else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) 725 | return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); 726 | else if (lexical.align) return lexical.column + (closing ? 0 : 1); 727 | else return lexical.indented + (closing ? 0 : indentUnit); 728 | }, 729 | 730 | electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, 731 | blockCommentStart: jsonMode ? null : "/*", 732 | blockCommentEnd: jsonMode ? null : "*/", 733 | lineComment: jsonMode ? null : "//", 734 | fold: "brace", 735 | closeBrackets: "()[]{}''\"\"``", 736 | 737 | helperType: jsonMode ? "json" : "javascript", 738 | jsonldMode: jsonldMode, 739 | jsonMode: jsonMode, 740 | 741 | expressionAllowed: expressionAllowed, 742 | skipExpression: function(state) { 743 | var top = state.cc[state.cc.length - 1] 744 | if (top == expression || top == expressionNoComma) state.cc.pop() 745 | } 746 | }; 747 | }); 748 | 749 | CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); 750 | 751 | CodeMirror.defineMIME("text/javascript", "javascript"); 752 | CodeMirror.defineMIME("text/ecmascript", "javascript"); 753 | CodeMirror.defineMIME("application/javascript", "javascript"); 754 | CodeMirror.defineMIME("application/x-javascript", "javascript"); 755 | CodeMirror.defineMIME("application/ecmascript", "javascript"); 756 | CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); 757 | CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); 758 | CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); 759 | CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); 760 | CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); 761 | 762 | }); 763 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/mode/javascript/json-ld.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: JSON-LD mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 27 | 28 |
29 |

JSON-LD mode

30 | 31 | 32 |
61 | 62 | 70 | 71 |

This is a specialization of the JavaScript mode.

72 |
73 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/mode/javascript/test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } 7 | 8 | MT("locals", 9 | "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }"); 10 | 11 | MT("comma-and-binop", 12 | "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }"); 13 | 14 | MT("destructuring", 15 | "([keyword function]([def a], [[[def b], [def c] ]]) {", 16 | " [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);", 17 | " [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];", 18 | "})();"); 19 | 20 | MT("destructure_trailing_comma", 21 | "[keyword let] {[def a], [def b],} [operator =] [variable foo];", 22 | "[keyword let] [def c];"); // Parser still in good state? 23 | 24 | MT("class_body", 25 | "[keyword class] [def Foo] {", 26 | " [property constructor]() {}", 27 | " [property sayName]() {", 28 | " [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];", 29 | " }", 30 | "}"); 31 | 32 | MT("class", 33 | "[keyword class] [def Point] [keyword extends] [variable SuperThing] {", 34 | " [property get] [property prop]() { [keyword return] [number 24]; }", 35 | " [property constructor]([def x], [def y]) {", 36 | " [keyword super]([string 'something']);", 37 | " [keyword this].[property x] [operator =] [variable-2 x];", 38 | " }", 39 | "}"); 40 | 41 | MT("import", 42 | "[keyword function] [def foo]() {", 43 | " [keyword import] [def $] [keyword from] [string 'jquery'];", 44 | " [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];", 45 | "}"); 46 | 47 | MT("import_trailing_comma", 48 | "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") 49 | 50 | MT("const", 51 | "[keyword function] [def f]() {", 52 | " [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", 53 | "}"); 54 | 55 | MT("for/of", 56 | "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); 57 | 58 | MT("generator", 59 | "[keyword function*] [def repeat]([def n]) {", 60 | " [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])", 61 | " [keyword yield] [variable-2 i];", 62 | "}"); 63 | 64 | MT("quotedStringAddition", 65 | "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); 66 | 67 | MT("quotedFatArrow", 68 | "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];"); 69 | 70 | MT("fatArrow", 71 | "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);", 72 | "[variable a];", // No longer in scope 73 | "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];", 74 | "[variable c];"); 75 | 76 | MT("spread", 77 | "[keyword function] [def f]([def a], [meta ...][def b]) {", 78 | " [variable something]([variable-2 a], [meta ...][variable-2 b]);", 79 | "}"); 80 | 81 | MT("quasi", 82 | "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); 83 | 84 | MT("quasi_no_function", 85 | "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); 86 | 87 | MT("indent_statement", 88 | "[keyword var] [def x] [operator =] [number 10]", 89 | "[variable x] [operator +=] [variable y] [operator +]", 90 | " [atom Infinity]", 91 | "[keyword debugger];"); 92 | 93 | MT("indent_if", 94 | "[keyword if] ([number 1])", 95 | " [keyword break];", 96 | "[keyword else] [keyword if] ([number 2])", 97 | " [keyword continue];", 98 | "[keyword else]", 99 | " [number 10];", 100 | "[keyword if] ([number 1]) {", 101 | " [keyword break];", 102 | "} [keyword else] [keyword if] ([number 2]) {", 103 | " [keyword continue];", 104 | "} [keyword else] {", 105 | " [number 10];", 106 | "}"); 107 | 108 | MT("indent_for", 109 | "[keyword for] ([keyword var] [def i] [operator =] [number 0];", 110 | " [variable i] [operator <] [number 100];", 111 | " [variable i][operator ++])", 112 | " [variable doSomething]([variable i]);", 113 | "[keyword debugger];"); 114 | 115 | MT("indent_c_style", 116 | "[keyword function] [def foo]()", 117 | "{", 118 | " [keyword debugger];", 119 | "}"); 120 | 121 | MT("indent_else", 122 | "[keyword for] (;;)", 123 | " [keyword if] ([variable foo])", 124 | " [keyword if] ([variable bar])", 125 | " [number 1];", 126 | " [keyword else]", 127 | " [number 2];", 128 | " [keyword else]", 129 | " [number 3];"); 130 | 131 | MT("indent_funarg", 132 | "[variable foo]([number 10000],", 133 | " [keyword function]([def a]) {", 134 | " [keyword debugger];", 135 | "};"); 136 | 137 | MT("indent_below_if", 138 | "[keyword for] (;;)", 139 | " [keyword if] ([variable foo])", 140 | " [number 1];", 141 | "[number 2];"); 142 | 143 | MT("multilinestring", 144 | "[keyword var] [def x] [operator =] [string 'foo\\]", 145 | "[string bar'];"); 146 | 147 | MT("scary_regexp", 148 | "[string-2 /foo[[/]]bar/];"); 149 | 150 | MT("indent_strange_array", 151 | "[keyword var] [def x] [operator =] [[", 152 | " [number 1],,", 153 | " [number 2],", 154 | "]];", 155 | "[number 10];"); 156 | 157 | MT("param_default", 158 | "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {", 159 | " [keyword return] [variable-2 x];", 160 | "}"); 161 | 162 | MT("new_target", 163 | "[keyword function] [def F]([def target]) {", 164 | " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", 165 | " [keyword return] [keyword new]", 166 | " .[keyword target];", 167 | " }", 168 | "}"); 169 | 170 | var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript") 171 | function TS(name) { 172 | test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) 173 | } 174 | 175 | TS("extend_type", 176 | "[keyword class] [def Foo] [keyword extends] [variable-3 Some][operator <][variable-3 Type][operator >] {}") 177 | 178 | TS("arrow_type", 179 | "[keyword let] [def x]: ([variable arg]: [variable-3 Type]) [operator =>] [variable-3 ReturnType]") 180 | 181 | var jsonld_mode = CodeMirror.getMode( 182 | {indentUnit: 2}, 183 | {name: "javascript", jsonld: true} 184 | ); 185 | function LD(name) { 186 | test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1)); 187 | } 188 | 189 | LD("json_ld_keywords", 190 | '{', 191 | ' [meta "@context"]: {', 192 | ' [meta "@base"]: [string "http://example.com"],', 193 | ' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],', 194 | ' [property "likesFlavor"]: {', 195 | ' [meta "@container"]: [meta "@list"]', 196 | ' [meta "@reverse"]: [string "@beFavoriteOf"]', 197 | ' },', 198 | ' [property "nick"]: { [meta "@container"]: [meta "@set"] },', 199 | ' [property "nick"]: { [meta "@container"]: [meta "@index"] }', 200 | ' },', 201 | ' [meta "@graph"]: [[ {', 202 | ' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],', 203 | ' [property "name"]: [string "John Lennon"],', 204 | ' [property "modified"]: {', 205 | ' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],', 206 | ' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]', 207 | ' }', 208 | ' } ]]', 209 | '}'); 210 | 211 | LD("json_ld_fake", 212 | '{', 213 | ' [property "@fake"]: [string "@fake"],', 214 | ' [property "@contextual"]: [string "@identifier"],', 215 | ' [property "user@domain.com"]: [string "@graphical"],', 216 | ' [property "@ID"]: [string "@@ID"]', 217 | '}'); 218 | })(); 219 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/mode/javascript/typescript.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: TypeScript mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
26 |

TypeScript mode

27 | 28 | 29 |
51 | 52 | 59 | 60 |

This is a specialization of the JavaScript mode.

61 |
62 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeMirror/theme/monokai.css: -------------------------------------------------------------------------------- 1 | /* Based on Sublime Text's Monokai theme */ 2 | 3 | .cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } 4 | .cm-s-monokai div.CodeMirror-selected { background: #49483E; } 5 | .cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } 6 | .cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } 7 | .cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } 8 | .cm-s-monokai .CodeMirror-guttermarker { color: white; } 9 | .cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 10 | .cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } 11 | .cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 12 | 13 | .cm-s-monokai span.cm-comment { color: #75715e; } 14 | .cm-s-monokai span.cm-atom { color: #ae81ff; } 15 | .cm-s-monokai span.cm-number { color: #ae81ff; } 16 | 17 | .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; } 18 | .cm-s-monokai span.cm-keyword { color: #f92672; } 19 | .cm-s-monokai span.cm-builtin { color: #66d9ef; } 20 | .cm-s-monokai span.cm-string { color: #e6db74; } 21 | 22 | .cm-s-monokai span.cm-variable { color: #f8f8f2; } 23 | .cm-s-monokai span.cm-variable-2 { color: #9effff; } 24 | .cm-s-monokai span.cm-variable-3 { color: #66d9ef; } 25 | .cm-s-monokai span.cm-def { color: #fd971f; } 26 | .cm-s-monokai span.cm-bracket { color: #f8f8f2; } 27 | .cm-s-monokai span.cm-tag { color: #f92672; } 28 | .cm-s-monokai span.cm-header { color: #ae81ff; } 29 | .cm-s-monokai span.cm-link { color: #ae81ff; } 30 | .cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } 31 | 32 | .cm-s-monokai .CodeMirror-activeline-background { background: #373831; } 33 | .cm-s-monokai .CodeMirror-matchingbracket { 34 | text-decoration: underline; 35 | color: white !important; 36 | } 37 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeSnippet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CodeSnippet.h 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface CodeSnippet : RLMObject 13 | 14 | @property (nonatomic, copy) NSString *ID; 15 | 16 | @property (nonatomic, copy) NSString *name; 17 | 18 | @property (nonatomic, copy) NSString *code; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ExtensionsForSafari/CodeSnippet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CodeSnippet.m 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "CodeSnippet.h" 10 | 11 | @implementation CodeSnippet 12 | 13 | + (NSString *)primaryKey { 14 | return @"ID"; 15 | } 16 | 17 | + (NSDictionary *)defaultPropertyValues { 18 | return @{@"code" : @"//write your code on here\\n"}; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /ExtensionsForSafari/EditorViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EditorViewController.h 3 | // JavaScriptInject 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CodeSnippet.h" 11 | 12 | @interface EditorViewController : UIViewController 13 | 14 | @property (nonatomic, strong) CodeSnippet *snippet; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ExtensionsForSafari/EditorViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EditorViewController.m 3 | // JavaScriptInject 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "EditorViewController.h" 10 | #import 11 | #import 12 | 13 | @interface EditorViewController () 14 | 15 | @property (nonatomic, strong) WKWebView *editorWebView; 16 | 17 | @property (nonatomic, copy) NSString *content; 18 | 19 | @end 20 | 21 | @implementation EditorViewController 22 | 23 | #pragma mark - Life Cycle 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | 28 | self.title = self.snippet.name; 29 | 30 | [self.view addSubview:self.editorWebView]; 31 | 32 | [self.editorWebView mas_makeConstraints:^(MASConstraintMaker *make) { 33 | make.top.equalTo(self.mas_topLayoutGuide); 34 | make.left.right.bottom.equalTo(self.view); 35 | }]; 36 | 37 | [self loadCodeMirror]; 38 | 39 | } 40 | 41 | #pragma mark - Event Response 42 | 43 | - (IBAction)didTapActionButton:(UIBarButtonItem *)sender { 44 | 45 | } 46 | 47 | #pragma mark - WKScriptMessageHandler 48 | 49 | - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { 50 | 51 | self.content = [message.body objectForKey:@"content"]; 52 | [self updateSnippet]; 53 | 54 | } 55 | 56 | #pragma mark - WKNavigationDelegate 57 | 58 | - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation { 59 | [self setCode:self.snippet.code]; 60 | } 61 | 62 | #pragma mark - Private Method 63 | 64 | - (void)updateSnippet { 65 | 66 | RLMRealm *realm = [RLMRealm defaultRealm]; 67 | 68 | [realm transactionWithBlock:^{ 69 | self.snippet.code = self.content; 70 | }]; 71 | } 72 | 73 | 74 | - (void)loadCodeMirror { 75 | 76 | NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"sublime" ofType:@"html" inDirectory:@"CodeMirror/html"]; 77 | NSURL *htmlURL = [NSURL fileURLWithPath:htmlPath]; 78 | 79 | NSString *codeMirrorPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/CodeMirror"]; 80 | NSURL *codeMirrorURL = [NSURL fileURLWithPath:codeMirrorPath]; 81 | 82 | [self.editorWebView loadFileURL:htmlURL allowingReadAccessToURL:codeMirrorURL]; 83 | 84 | } 85 | 86 | - (void)setCode:(NSString *)code { 87 | [self.editorWebView evaluateJavaScript:[NSString stringWithFormat:@"setCode('%@')", code] completionHandler:nil]; 88 | } 89 | 90 | - (void)getCodeSuccess:(void (^)(NSString *code))success { 91 | [self.editorWebView evaluateJavaScript:@"getCode()" completionHandler:^(id _Nullable result, NSError * _Nullable error) { 92 | self.content = result; 93 | }]; 94 | } 95 | 96 | #pragma mark - Getter 97 | 98 | - (WKWebView *)editorWebView { 99 | if (!_editorWebView) { 100 | WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; 101 | //注册js方法 102 | [config.userContentController addScriptMessageHandler:self name:@"CodeMirrorChangeEvent"]; 103 | _editorWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config]; 104 | _editorWebView.scrollView.bounces = NO; 105 | _editorWebView.scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite; 106 | _editorWebView.navigationDelegate = self; 107 | } 108 | return _editorWebView; 109 | } 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /ExtensionsForSafari/ExtensionsForSafari.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.jerrytian.extensionsforsafari 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ExtensionsForSafari/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | CFBundleDisplayName 47 | Extensions 48 | 49 | 50 | -------------------------------------------------------------------------------- /ExtensionsForSafari/SnippetTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SnippetTableViewCell.h 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SnippetTableViewCell : UITableViewCell 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ExtensionsForSafari/SnippetTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SnippetTableViewCell.m 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "SnippetTableViewCell.h" 10 | 11 | @implementation SnippetTableViewCell 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 19 | [super setSelected:selected animated:animated]; 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ExtensionsForSafari/SnippetTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /ExtensionsForSafari/SnippetsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SnippetsTableViewController.h 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SnippetsTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExtensionsForSafari/SnippetsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SnippetsTableViewController.m 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/31. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "SnippetsTableViewController.h" 10 | #import "EditorViewController.h" 11 | #import "SnippetTableViewCell.h" 12 | 13 | @interface SnippetsTableViewController () 14 | 15 | @property (nonatomic, strong) RLMResults *snippets; 16 | 17 | @end 18 | 19 | @implementation SnippetsTableViewController 20 | 21 | #pragma mark - Life Cycle 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | [self.tableView registerNib:[UINib nibWithNibName:@"SnippetTableViewCell" bundle:nil] forCellReuseIdentifier:@"SnippetTableViewCell"]; 26 | } 27 | 28 | - (void)viewWillAppear:(BOOL)animated { 29 | [super viewWillAppear:animated]; 30 | [self loadSnippets]; 31 | } 32 | 33 | - (IBAction)didTapAddSnippetButton:(UIBarButtonItem *)sender { 34 | [self createNewSnippetSuccess:^(CodeSnippet *snippet) { 35 | if (snippet) { 36 | [self performSegueWithIdentifier:@"ShowEditorSegue" sender:snippet]; 37 | } 38 | }]; 39 | } 40 | 41 | #pragma mark - UITableViewDataSource 42 | 43 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 44 | return self.snippets.count; 45 | } 46 | 47 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 48 | SnippetTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SnippetTableViewCell" forIndexPath:indexPath]; 49 | CodeSnippet *snippet = [self.snippets objectAtIndex:indexPath.row]; 50 | cell.nameLabel.text = snippet.name; 51 | 52 | return cell; 53 | } 54 | 55 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 56 | return YES; 57 | } 58 | 59 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 60 | if (editingStyle == UITableViewCellEditingStyleDelete) { 61 | CodeSnippet *snippet = [self.snippets objectAtIndex:indexPath.row]; 62 | 63 | RLMRealm *realm = [RLMRealm defaultRealm]; 64 | 65 | [realm transactionWithBlock:^{ 66 | [realm deleteObject:snippet]; 67 | }]; 68 | 69 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 70 | } 71 | } 72 | 73 | #pragma mark - UITableViewDelegate 74 | 75 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 76 | CodeSnippet *snippet = [self.snippets objectAtIndex:indexPath.row]; 77 | 78 | [self performSegueWithIdentifier:@"ShowEditorSegue" sender:snippet]; 79 | } 80 | 81 | 82 | #pragma mark - Navigation 83 | 84 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 85 | if ([segue.identifier isEqualToString:@"ShowEditorSegue"]) { 86 | if ([sender isKindOfClass:[CodeSnippet class]]) { 87 | EditorViewController *editorViewController = segue.destinationViewController; 88 | editorViewController.snippet = sender; 89 | } 90 | } 91 | } 92 | 93 | #pragma mark - Private Method 94 | 95 | - (void)loadSnippets { 96 | self.snippets = [CodeSnippet allObjects]; 97 | if (!self.snippets.count) { 98 | 99 | } 100 | [self.tableView reloadData]; 101 | } 102 | 103 | - (void)createNewSnippetSuccess:(void (^)(CodeSnippet *snippet))success { 104 | 105 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"新建代码片段" message:nil preferredStyle:UIAlertControllerStyleAlert]; 106 | [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { 107 | textField.placeholder = @"名称"; 108 | }]; 109 | [alertController addAction:[UIAlertAction actionWithTitle:@"创建" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 110 | 111 | CodeSnippet *snippet = [[CodeSnippet alloc] init]; 112 | snippet.ID = [[NSUUID UUID] UUIDString]; 113 | snippet.name = alertController.textFields.firstObject.text; 114 | 115 | RLMRealm *realm = [RLMRealm defaultRealm]; 116 | [realm transactionWithBlock:^{ 117 | [realm addObject:snippet]; 118 | }]; 119 | success(snippet); 120 | }]]; 121 | [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]]; 122 | 123 | [self presentViewController:alertController animated:YES completion:nil]; 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /ExtensionsForSafari/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ExtensionsForSafari 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/ActionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ActionViewController.h 3 | // ExtensionsForSafariAction 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ActionViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/ActionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ActionViewController.m 3 | // ExtensionsForSafariAction 4 | // 5 | // Created by Tian on 16/8/30. 6 | // Copyright © 2016年 JerryTian. All rights reserved. 7 | // 8 | 9 | #import "ActionViewController.h" 10 | #import 11 | #import 12 | #import "SnippetTableViewCell.h" 13 | #import "CodeSnippet.h" 14 | 15 | @interface ActionViewController () 16 | 17 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 18 | 19 | @property (nonatomic, strong) RLMResults *snippets; 20 | 21 | @end 22 | 23 | @implementation ActionViewController 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | 28 | RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration]; 29 | configuration.fileURL = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.jerrytian.extensionsforsafari"] URLByAppendingPathComponent:@"db.realm"]; 30 | [RLMRealmConfiguration setDefaultConfiguration:configuration]; 31 | 32 | [self.tableView registerNib:[UINib nibWithNibName:@"SnippetTableViewCell" bundle:nil] forCellReuseIdentifier:@"SnippetTableViewCell"]; 33 | 34 | [self loadSnippets]; 35 | 36 | BOOL foundDictionary = NO; 37 | for (NSExtensionItem *item in self.extensionContext.inputItems) 38 | { 39 | for (NSItemProvider *itemProvider in item.attachments) 40 | { 41 | if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePropertyList]) 42 | { 43 | [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *dictionary, NSError *error) { 44 | if (dictionary != nil) 45 | { 46 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 47 | NSDictionary *jsDict = dictionary[NSExtensionJavaScriptPreprocessingResultsKey]; 48 | if (jsDict != nil) 49 | { 50 | NSString *urlStr = jsDict[@"baseURI"]; 51 | NSLog(@"%@", urlStr); 52 | } 53 | }]; 54 | } 55 | }]; 56 | 57 | foundDictionary = YES; 58 | break; 59 | } 60 | } 61 | 62 | if (foundDictionary) 63 | break; 64 | } 65 | } 66 | 67 | 68 | #pragma mark - Event Response 69 | 70 | - (IBAction)didTapFireBugButton:(UIBarButtonItem *)sender { 71 | NSString *fireBugJs = 72 | @"(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F[i+'NS']&&F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened')"; 73 | [self excuteJavaScriptOnSafari:fireBugJs]; 74 | } 75 | 76 | #pragma mark - UITableViewDataSource 77 | 78 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 79 | return self.snippets.count; 80 | } 81 | 82 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 83 | SnippetTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SnippetTableViewCell" forIndexPath:indexPath]; 84 | CodeSnippet *snippet = [self.snippets objectAtIndex:indexPath.row]; 85 | cell.nameLabel.text = snippet.name; 86 | 87 | return cell; 88 | } 89 | 90 | #pragma mark - UITableViewDelegate 91 | 92 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 93 | CodeSnippet *snippet = [self.snippets objectAtIndex:indexPath.row]; 94 | 95 | [self excuteJavaScriptOnSafari:snippet.code]; 96 | } 97 | 98 | - (IBAction)done { 99 | [self.extensionContext completeRequestReturningItems:nil completionHandler:nil]; 100 | } 101 | 102 | #pragma mark - Private Method 103 | 104 | - (void)loadSnippets { 105 | self.snippets = [CodeSnippet allObjects]; 106 | [self.tableView reloadData]; 107 | } 108 | 109 | 110 | - (void)excuteJavaScriptOnSafari:(NSString *)js { 111 | NSExtensionItem *extensionItem = [[NSExtensionItem alloc] init]; 112 | extensionItem.attachments = @[[[NSItemProvider alloc] initWithItem: @{NSExtensionJavaScriptFinalizeArgumentKey: @{@"jsCode" : js}} typeIdentifier:(NSString *)kUTTypePropertyList]]; 113 | 114 | [self.extensionContext completeRequestReturningItems:@[extensionItem] completionHandler:nil]; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/ExtensionsForSafariAction.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.jerrytian.extensionsforsafari 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleDisplayName 8 | Extensions 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | NSExtensionActivationRule 30 | 31 | NSExtensionActivationSupportsWebPageWithMaxCount 32 | 1 33 | 34 | NSExtensionJavaScriptPreprocessingFile 35 | Inject 36 | 37 | NSExtensionMainStoryboard 38 | MainInterface 39 | NSExtensionPointIdentifier 40 | com.apple.ui-services 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ExtensionsForSafariAction/Inject.js: -------------------------------------------------------------------------------- 1 | var MyExtensionJavaScriptClass = function() {}; 2 | 3 | MyExtensionJavaScriptClass.prototype = { 4 | run: function(arguments) { 5 | // Pass the baseURI of the webpage to the extension. 6 | arguments.completionFunction({"baseURI": document.baseURI}); 7 | }, 8 | 9 | // Note that the finalize function is only available in iOS. 10 | finalize: function(arguments) { 11 | // arguments contains the value the extension provides in [NSExtensionContext completeRequestReturningItems:completion:]. 12 | // In this example, the extension provides a color as a returning item. 13 | eval(unescape(arguments["jsCode"])); 14 | } 15 | }; 16 | 17 | // The JavaScript file must contain a global object named "ExtensionPreprocessingJS". 18 | var ExtensionPreprocessingJS = new MyExtensionJavaScriptClass; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jianan Tian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | use_frameworks! 3 | 4 | target 'ExtensionsForSafari' do 5 | pod 'Realm' 6 | pod 'Masonry' 7 | end 8 | 9 | target 'ExtensionsForSafariAction' do 10 | pod 'Realm' 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Masonry (1.0.1) 3 | - Realm (1.0.2): 4 | - Realm/Headers (= 1.0.2) 5 | - Realm/Headers (1.0.2) 6 | 7 | DEPENDENCIES: 8 | - Masonry 9 | - Realm 10 | 11 | SPEC CHECKSUMS: 12 | Masonry: a1a931a0d08870ed8ae415a2ea5ea68ebcac77df 13 | Realm: 9d5c46a4d7d27958530a8dfc58f63a99e5c2cba3 14 | 15 | PODFILE CHECKSUM: 88fd858183b282751c487d49ee6f925b131a0343 16 | 17 | COCOAPODS: 1.1.0.beta.1 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Extensions-For-Safari 2 | 3 | 这个小程序是用来在Safari中注入JavaScript代码用的.有兴趣的可以看看我写的详细的[实现过程](http://kanam.me/2016/08/30/2016-08-30/) 4 | 5 | 程序需要正确的设置App Groups才能正常的使用. 6 | 7 | ## ScreenShots 8 | ![](https://raw.githubusercontent.com/JNTian/Extensions-For-Safari/master/screenshot1.PNG) 9 | ![](https://raw.githubusercontent.com/JNTian/Extensions-For-Safari/master/screenshot2.PNG) 10 | ![](https://raw.githubusercontent.com/JNTian/Extensions-For-Safari/master/screenshot3.PNG) 11 | -------------------------------------------------------------------------------- /screenshot1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/screenshot1.PNG -------------------------------------------------------------------------------- /screenshot2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/screenshot2.PNG -------------------------------------------------------------------------------- /screenshot3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikanam/Extensions-For-Safari/feec1f11bd6e4b04a91ff0daaf993cac5863ec0b/screenshot3.PNG --------------------------------------------------------------------------------