瀏覽代碼

initial commit

Artal Druk 8 年之前
當前提交
85d5ce01d3
共有 46 個文件被更改,包括 3986 次插入0 次删除
  1. 44
    0
      .gitignore
  2. 224
    0
      .npmignore
  3. 66
    0
      example/android/app/BUCK
  4. 140
    0
      example/android/app/build.gradle
  5. 66
    0
      example/android/app/proguard-rules.pro
  6. 31
    0
      example/android/app/src/main/AndroidManifest.xml
  7. 7
    0
      example/android/app/src/main/java/com/react_native_navigation_bootstrap/MainActivity.java
  8. 25
    0
      example/android/app/src/main/java/com/react_native_navigation_bootstrap/MainApplication.java
  9. 二進制
      example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  10. 二進制
      example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  11. 二進制
      example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  12. 二進制
      example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  13. 3
    0
      example/android/app/src/main/res/values/strings.xml
  14. 8
    0
      example/android/app/src/main/res/values/styles.xml
  15. 24
    0
      example/android/build.gradle
  16. 20
    0
      example/android/gradle.properties
  17. 二進制
      example/android/gradle/wrapper/gradle-wrapper.jar
  18. 6
    0
      example/android/gradle/wrapper/gradle-wrapper.properties
  19. 164
    0
      example/android/gradlew
  20. 90
    0
      example/android/gradlew.bat
  21. 8
    0
      example/android/keystores/BUCK
  22. 4
    0
      example/android/keystores/debug.keystore.properties
  23. 6
    0
      example/android/settings.gradle
  24. 60
    0
      example/index.android.js
  25. 38
    0
      example/index.ios.js
  26. 796
    0
      example/ios/react_native_navigation_bootstrap.xcodeproj/project.pbxproj
  27. 112
    0
      example/ios/react_native_navigation_bootstrap.xcodeproj/xcshareddata/xcschemes/react_native_navigation_bootstrap.xcscheme
  28. 16
    0
      example/ios/react_native_navigation_bootstrap/AppDelegate.h
  29. 42
    0
      example/ios/react_native_navigation_bootstrap/AppDelegate.m
  30. 42
    0
      example/ios/react_native_navigation_bootstrap/Base.lproj/LaunchScreen.xib
  31. 38
    0
      example/ios/react_native_navigation_bootstrap/Images.xcassets/AppIcon.appiconset/Contents.json
  32. 55
    0
      example/ios/react_native_navigation_bootstrap/Info.plist
  33. 18
    0
      example/ios/react_native_navigation_bootstrap/main.m
  34. 24
    0
      example/ios/react_native_navigation_bootstrapTests/Info.plist
  35. 70
    0
      example/ios/react_native_navigation_bootstrapTests/react_native_navigation_bootstrapTests.m
  36. 13
    0
      example/package.json
  37. 2
    0
      index.js
  38. 22
    0
      package.json
  39. 152
    0
      src/RichTextEditor.js
  40. 14
    0
      src/WebviewMessageHandler.js
  41. 766
    0
      src/ZSSRichTextEditor/JSBeautifier.js
  42. 689
    0
      src/ZSSRichTextEditor/ZSSRichTextEditor.js
  43. 4
    0
      src/ZSSRichTextEditor/jQuery.js
  44. 51
    0
      src/ZSSRichTextEditor/style.css
  45. 4
    0
      src/const.js
  46. 22
    0
      src/editor.html

+ 44
- 0
.gitignore 查看文件

@@ -0,0 +1,44 @@
1
+# OSX
2
+#
3
+.DS_Store
4
+
5
+# Xcode
6
+#
7
+build/
8
+*.pbxuser
9
+!default.pbxuser
10
+*.mode1v3
11
+!default.mode1v3
12
+*.mode2v3
13
+!default.mode2v3
14
+*.perspectivev3
15
+!default.perspectivev3
16
+xcuserdata
17
+*.xccheckout
18
+*.moved-aside
19
+DerivedData
20
+*.hmap
21
+*.ipa
22
+*.xcuserstate
23
+project.xcworkspace
24
+
25
+# Android/IJ
26
+#
27
+.idea
28
+.gradle
29
+local.properties
30
+
31
+# node.js
32
+#
33
+node_modules/
34
+npm-debug.log
35
+
36
+# BUCK
37
+buck-out/
38
+\.buckd/
39
+android/app/libs
40
+android/keystores/debug.keystore
41
+android/*.iml
42
+android/app/*.iml
43
+yarn.lock
44
+*.log

+ 224
- 0
.npmignore 查看文件

@@ -0,0 +1,224 @@
1
+example/
2
+
3
+test/
4
+res/generated/
5
+
6
+.npmignore
7
+
8
+
9
+#################
10
+# from .gitignore:
11
+################
12
+
13
+
14
+############
15
+# Node
16
+############
17
+# Logs
18
+logs
19
+*.log
20
+npm-debug.log*
21
+
22
+# Runtime data
23
+pids
24
+*.pid
25
+*.seed
26
+
27
+# Directory for instrumented libs generated by jscoverage/JSCover
28
+lib-cov
29
+
30
+# Coverage directory used by tools like istanbul
31
+coverage
32
+
33
+# nyc test coverage
34
+.nyc_output
35
+
36
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
37
+.grunt
38
+
39
+# node-waf configuration
40
+.lock-wscript
41
+
42
+# Compiled binary addons (http://nodejs.org/api/addons.html)
43
+build/Release
44
+
45
+# Dependency directories
46
+node_modules
47
+jspm_packages
48
+
49
+# Optional npm cache directory
50
+.npm
51
+
52
+# Optional REPL history
53
+.node_repl_history
54
+
55
+################
56
+# JetBrains
57
+################
58
+.idea
59
+
60
+## File-based project format:
61
+*.iws
62
+
63
+## Plugin-specific files:
64
+
65
+# IntelliJ
66
+/out/
67
+
68
+# mpeltonen/sbt-idea plugin
69
+.idea_modules/
70
+
71
+# JIRA plugin
72
+atlassian-ide-plugin.xml
73
+
74
+# Crashlytics plugin (for Android Studio and IntelliJ)
75
+com_crashlytics_export_strings.xml
76
+crashlytics.properties
77
+crashlytics-build.properties
78
+fabric.properties
79
+
80
+
81
+############
82
+# iOS
83
+############
84
+# Xcode
85
+#
86
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
87
+
88
+## Build generated
89
+ios/build/
90
+ios/DerivedData/
91
+
92
+## Various settings
93
+*.pbxuser
94
+!default.pbxuser
95
+*.mode1v3
96
+!default.mode1v3
97
+*.mode2v3
98
+!default.mode2v3
99
+*.perspectivev3
100
+!default.perspectivev3
101
+ios/xcuserdata/
102
+
103
+## Other
104
+*.moved-aside
105
+*.xcuserstate
106
+
107
+## Obj-C/Swift specific
108
+*.hmap
109
+*.ipa
110
+*.dSYM.zip
111
+*.dSYM
112
+
113
+# CocoaPods
114
+#
115
+# We recommend against adding the Pods directory to your .gitignore. However
116
+# you should judge for yourself, the pros and cons are mentioned at:
117
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
118
+#
119
+ios/Pods/
120
+
121
+# Carthage
122
+#
123
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
124
+# Carthage/Checkouts
125
+
126
+Carthage/Build
127
+
128
+# fastlane
129
+#
130
+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
131
+# screenshots whenever they are needed.
132
+# For more information about the recommended setup visit:
133
+# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
134
+
135
+fastlane/report.xml
136
+fastlane/screenshots
137
+
138
+
139
+############
140
+# Android
141
+############
142
+# Built application files
143
+*.apk
144
+*.ap_
145
+
146
+# Files for the Dalvik VM
147
+*.dex
148
+
149
+# Java class files
150
+*.class
151
+
152
+# Generated files
153
+android/bin/
154
+android/gen/
155
+android/out/
156
+
157
+# Gradle files
158
+android/.gradle/
159
+android/build/
160
+
161
+# Local configuration file (sdk path, etc)
162
+local.properties
163
+
164
+# Proguard folder generated by Eclipse
165
+android/proguard/
166
+
167
+# Log Files
168
+*.log
169
+
170
+# Android Studio Navigation editor temp files
171
+android/.navigation/
172
+
173
+# Android Studio captures folder
174
+android/captures/
175
+
176
+# Intellij
177
+*.iml
178
+
179
+# Keystore files
180
+*.jks
181
+
182
+##################
183
+# React-Native
184
+##################
185
+# OSX
186
+#
187
+.DS_Store
188
+
189
+# Xcode
190
+#
191
+build/
192
+*.pbxuser
193
+!default.pbxuser
194
+*.mode1v3
195
+!default.mode1v3
196
+*.mode2v3
197
+!default.mode2v3
198
+*.perspectivev3
199
+!default.perspectivev3
200
+xcuserdata
201
+*.xccheckout
202
+*.moved-aside
203
+DerivedData
204
+*.hmap
205
+*.ipa
206
+*.xcuserstate
207
+project.xcworkspace
208
+
209
+# Android/IJ
210
+#
211
+.idea
212
+.gradle
213
+local.properties
214
+
215
+# node.js
216
+#
217
+node_modules/
218
+npm-debug.log
219
+
220
+# BUCK
221
+buck-out/
222
+\.buckd/
223
+android/app/libs
224
+android/keystores/debug.keystore

+ 66
- 0
example/android/app/BUCK 查看文件

@@ -0,0 +1,66 @@
1
+import re
2
+
3
+# To learn about Buck see [Docs](https://buckbuild.com/).
4
+# To run your application with Buck:
5
+# - install Buck
6
+# - `npm start` - to start the packager
7
+# - `cd android`
8
+# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
9
+# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
10
+# - `buck install -r android/app` - compile, install and run application
11
+#
12
+
13
+lib_deps = []
14
+for jarfile in glob(['libs/*.jar']):
15
+  name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile)
16
+  lib_deps.append(':' + name)
17
+  prebuilt_jar(
18
+    name = name,
19
+    binary_jar = jarfile,
20
+  )
21
+
22
+for aarfile in glob(['libs/*.aar']):
23
+  name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile)
24
+  lib_deps.append(':' + name)
25
+  android_prebuilt_aar(
26
+    name = name,
27
+    aar = aarfile,
28
+  )
29
+
30
+android_library(
31
+  name = 'all-libs',
32
+  exported_deps = lib_deps
33
+)
34
+
35
+android_library(
36
+  name = 'app-code',
37
+  srcs = glob([
38
+    'src/main/java/**/*.java',
39
+  ]),
40
+  deps = [
41
+    ':all-libs',
42
+    ':build_config',
43
+    ':res',
44
+  ],
45
+)
46
+
47
+android_build_config(
48
+  name = 'build_config',
49
+  package = 'com.react_native_navigation_bootstrap',
50
+)
51
+
52
+android_resource(
53
+  name = 'res',
54
+  res = 'src/main/res',
55
+  package = 'com.react_native_navigation_bootstrap',
56
+)
57
+
58
+android_binary(
59
+  name = 'app',
60
+  package_type = 'debug',
61
+  manifest = 'src/main/AndroidManifest.xml',
62
+  keystore = '//android/keystores:debug',
63
+  deps = [
64
+    ':app-code',
65
+  ],
66
+)

+ 140
- 0
example/android/app/build.gradle 查看文件

@@ -0,0 +1,140 @@
1
+apply plugin: "com.android.application"
2
+
3
+import com.android.build.OutputFile
4
+
5
+/**
6
+ * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7
+ * and bundleReleaseJsAndAssets).
8
+ * These basically call `react-native bundle` with the correct arguments during the Android build
9
+ * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10
+ * bundle directly from the development server. Below you can see all the possible configurations
11
+ * and their defaults. If you decide to add a configuration block, make sure to add it before the
12
+ * `apply from: "../../node_modules/react-native/react.gradle"` line.
13
+ *
14
+ * project.ext.react = [
15
+ *   // the name of the generated asset file containing your JS bundle
16
+ *   bundleAssetName: "index.android.bundle",
17
+ *
18
+ *   // the entry file for bundle generation
19
+ *   entryFile: "index.android.js",
20
+ *
21
+ *   // whether to bundle JS and assets in debug mode
22
+ *   bundleInDebug: false,
23
+ *
24
+ *   // whether to bundle JS and assets in release mode
25
+ *   bundleInRelease: true,
26
+ *
27
+ *   // whether to bundle JS and assets in another build variant (if configured).
28
+ *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
29
+ *   // The configuration property can be in the following formats
30
+ *   //         'bundleIn${productFlavor}${buildType}'
31
+ *   //         'bundleIn${buildType}'
32
+ *   // bundleInFreeDebug: true,
33
+ *   // bundleInPaidRelease: true,
34
+ *   // bundleInBeta: true,
35
+ *
36
+ *   // the root of your project, i.e. where "package.json" lives
37
+ *   root: "../../",
38
+ *
39
+ *   // where to put the JS bundle asset in debug mode
40
+ *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
41
+ *
42
+ *   // where to put the JS bundle asset in release mode
43
+ *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
44
+ *
45
+ *   // where to put drawable resources / React Native assets, e.g. the ones you use via
46
+ *   // require('./image.png')), in debug mode
47
+ *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
48
+ *
49
+ *   // where to put drawable resources / React Native assets, e.g. the ones you use via
50
+ *   // require('./image.png')), in release mode
51
+ *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
52
+ *
53
+ *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
54
+ *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
55
+ *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
56
+ *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
57
+ *   // for example, you might want to remove it from here.
58
+ *   inputExcludes: ["android/**", "ios/**"],
59
+ *
60
+ *   // override which node gets called and with what additional arguments
61
+ *   nodeExecutableAndArgs: ["node"]
62
+ *
63
+ *   // supply additional arguments to the packager
64
+ *   extraPackagerArgs: []
65
+ * ]
66
+ */
67
+
68
+apply from: "../../node_modules/react-native/react.gradle"
69
+
70
+/**
71
+ * Set this to true to create two separate APKs instead of one:
72
+ *   - An APK that only works on ARM devices
73
+ *   - An APK that only works on x86 devices
74
+ * The advantage is the size of the APK is reduced by about 4MB.
75
+ * Upload all the APKs to the Play Store and people will download
76
+ * the correct one based on the CPU architecture of their device.
77
+ */
78
+def enableSeparateBuildPerCPUArchitecture = false
79
+
80
+/**
81
+ * Run Proguard to shrink the Java bytecode in release builds.
82
+ */
83
+def enableProguardInReleaseBuilds = false
84
+
85
+android {
86
+    compileSdkVersion 23
87
+    buildToolsVersion "23.0.1"
88
+
89
+    defaultConfig {
90
+        applicationId "com.react_native_navigation_bootstrap"
91
+        minSdkVersion 16
92
+        targetSdkVersion 22
93
+        versionCode 1
94
+        versionName "1.0"
95
+        ndk {
96
+            abiFilters "armeabi-v7a", "x86"
97
+        }
98
+    }
99
+    splits {
100
+        abi {
101
+            reset()
102
+            enable enableSeparateBuildPerCPUArchitecture
103
+            universalApk false  // If true, also generate a universal APK
104
+            include "armeabi-v7a", "x86"
105
+        }
106
+    }
107
+    buildTypes {
108
+        release {
109
+            minifyEnabled enableProguardInReleaseBuilds
110
+            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
111
+        }
112
+    }
113
+    // applicationVariants are e.g. debug, release
114
+    applicationVariants.all { variant ->
115
+        variant.outputs.each { output ->
116
+            // For each separate APK per architecture, set a unique version code as described here:
117
+            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
118
+            def versionCodes = ["armeabi-v7a":1, "x86":2]
119
+            def abi = output.getFilter(OutputFile.ABI)
120
+            if (abi != null) {  // null for the universal-debug, universal-release variants
121
+                output.versionCodeOverride =
122
+                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
123
+            }
124
+        }
125
+    }
126
+}
127
+
128
+dependencies {
129
+    compile fileTree(dir: "libs", include: ["*.jar"])
130
+    compile "com.android.support:appcompat-v7:23.0.1"
131
+    compile "com.facebook.react:react-native:+"  // From node_modules
132
+    compile project(":react-native-navigation")
133
+}
134
+
135
+// Run this once to be able to run the application with BUCK
136
+// puts all compile dependencies into folder libs for BUCK to use
137
+task copyDownloadableDepsToLibs(type: Copy) {
138
+  from configurations.compile
139
+  into 'libs'
140
+}

+ 66
- 0
example/android/app/proguard-rules.pro 查看文件

@@ -0,0 +1,66 @@
1
+# Add project specific ProGuard rules here.
2
+# By default, the flags in this file are appended to flags specified
3
+# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4
+# You can edit the include path and order by changing the proguardFiles
5
+# directive in build.gradle.
6
+#
7
+# For more details, see
8
+#   http://developer.android.com/guide/developing/tools/proguard.html
9
+
10
+# Add any project specific keep options here:
11
+
12
+# If your project uses WebView with JS, uncomment the following
13
+# and specify the fully qualified class name to the JavaScript interface
14
+# class:
15
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16
+#   public *;
17
+#}
18
+
19
+# Disabling obfuscation is useful if you collect stack traces from production crashes
20
+# (unless you are using a system that supports de-obfuscate the stack traces).
21
+-dontobfuscate
22
+
23
+# React Native
24
+
25
+# Keep our interfaces so they can be used by other ProGuard rules.
26
+# See http://sourceforge.net/p/proguard/bugs/466/
27
+-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28
+-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29
+-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30
+
31
+# Do not strip any method/class that is annotated with @DoNotStrip
32
+-keep @com.facebook.proguard.annotations.DoNotStrip class *
33
+-keep @com.facebook.common.internal.DoNotStrip class *
34
+-keepclassmembers class * {
35
+    @com.facebook.proguard.annotations.DoNotStrip *;
36
+    @com.facebook.common.internal.DoNotStrip *;
37
+}
38
+
39
+-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40
+  void set*(***);
41
+  *** get*();
42
+}
43
+
44
+-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45
+-keep class * extends com.facebook.react.bridge.NativeModule { *; }
46
+-keepclassmembers,includedescriptorclasses class * { native <methods>; }
47
+-keepclassmembers class *  { @com.facebook.react.uimanager.UIProp <fields>; }
48
+-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
49
+-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
50
+
51
+-dontwarn com.facebook.react.**
52
+
53
+# okhttp
54
+
55
+-keepattributes Signature
56
+-keepattributes *Annotation*
57
+-keep class okhttp3.** { *; }
58
+-keep interface okhttp3.** { *; }
59
+-dontwarn okhttp3.**
60
+
61
+# okio
62
+
63
+-keep class sun.misc.Unsafe { *; }
64
+-dontwarn java.nio.file.*
65
+-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
66
+-dontwarn okio.**

+ 31
- 0
example/android/app/src/main/AndroidManifest.xml 查看文件

@@ -0,0 +1,31 @@
1
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+    package="com.react_native_navigation_bootstrap"
3
+    android:versionCode="1"
4
+    android:versionName="1.0">
5
+
6
+    <uses-permission android:name="android.permission.INTERNET" />
7
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
8
+
9
+    <uses-sdk
10
+        android:minSdkVersion="16"
11
+        android:targetSdkVersion="22" />
12
+
13
+    <application
14
+      android:name=".MainApplication"
15
+      android:allowBackup="true"
16
+      android:label="@string/app_name"
17
+      android:icon="@mipmap/ic_launcher"
18
+      android:theme="@style/AppTheme">
19
+      <activity
20
+        android:name=".MainActivity"
21
+        android:label="@string/app_name"
22
+        android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
23
+        <intent-filter>
24
+            <action android:name="android.intent.action.MAIN" />
25
+            <category android:name="android.intent.category.LAUNCHER" />
26
+        </intent-filter>
27
+      </activity>
28
+      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
29
+    </application>
30
+
31
+</manifest>

+ 7
- 0
example/android/app/src/main/java/com/react_native_navigation_bootstrap/MainActivity.java 查看文件

@@ -0,0 +1,7 @@
1
+package com.react_native_navigation_bootstrap;
2
+
3
+import com.reactnativenavigation.controllers.SplashActivity;
4
+
5
+public class MainActivity extends SplashActivity {
6
+
7
+}

+ 25
- 0
example/android/app/src/main/java/com/react_native_navigation_bootstrap/MainApplication.java 查看文件

@@ -0,0 +1,25 @@
1
+package com.react_native_navigation_bootstrap;
2
+
3
+import android.support.annotation.NonNull;
4
+
5
+import com.facebook.react.ReactPackage;
6
+import com.reactnativenavigation.NavigationApplication;
7
+
8
+import java.util.List;
9
+
10
+public class MainApplication extends NavigationApplication {
11
+
12
+  @Override
13
+  public boolean isDebug() {
14
+    return BuildConfig.DEBUG;
15
+  }
16
+
17
+  @NonNull
18
+  @Override
19
+  public List<ReactPackage> createAdditionalReactPackages() {
20
+    // Add the packages you require here.
21
+    // No need to add RnnPackage and MainReactPackage
22
+    return null;
23
+  }
24
+
25
+}

二進制
example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png 查看文件


二進制
example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png 查看文件


二進制
example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png 查看文件


二進制
example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png 查看文件


+ 3
- 0
example/android/app/src/main/res/values/strings.xml 查看文件

@@ -0,0 +1,3 @@
1
+<resources>
2
+    <string name="app_name">react_native_navigation_bootstrap</string>
3
+</resources>

+ 8
- 0
example/android/app/src/main/res/values/styles.xml 查看文件

@@ -0,0 +1,8 @@
1
+<resources>
2
+
3
+    <!-- Base application theme. -->
4
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
5
+        <!-- Customize your theme here. -->
6
+    </style>
7
+
8
+</resources>

+ 24
- 0
example/android/build.gradle 查看文件

@@ -0,0 +1,24 @@
1
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
2
+
3
+buildscript {
4
+    repositories {
5
+        jcenter()
6
+    }
7
+    dependencies {
8
+        classpath 'com.android.tools.build:gradle:1.3.1'
9
+
10
+        // NOTE: Do not place your application dependencies here; they belong
11
+        // in the individual module build.gradle files
12
+    }
13
+}
14
+
15
+allprojects {
16
+    repositories {
17
+        mavenLocal()
18
+        jcenter()
19
+        maven {
20
+            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21
+            url "$rootDir/../node_modules/react-native/android"
22
+        }
23
+    }
24
+}

+ 20
- 0
example/android/gradle.properties 查看文件

@@ -0,0 +1,20 @@
1
+# Project-wide Gradle settings.
2
+
3
+# IDE (e.g. Android Studio) users:
4
+# Gradle settings configured through the IDE *will override*
5
+# any settings specified in this file.
6
+
7
+# For more details on how to configure your build environment visit
8
+# http://www.gradle.org/docs/current/userguide/build_environment.html
9
+
10
+# Specifies the JVM arguments used for the daemon process.
11
+# The setting is particularly useful for tweaking memory settings.
12
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
13
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14
+
15
+# When configured, Gradle will run in incubating parallel mode.
16
+# This option should only be used with decoupled projects. More details, visit
17
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18
+# org.gradle.parallel=true
19
+
20
+android.useDeprecatedNdk=true

二進制
example/android/gradle/wrapper/gradle-wrapper.jar 查看文件


+ 6
- 0
example/android/gradle/wrapper/gradle-wrapper.properties 查看文件

@@ -0,0 +1,6 @@
1
+#Wed Aug 17 16:46:17 IDT 2016
2
+distributionBase=GRADLE_USER_HOME
3
+distributionPath=wrapper/dists
4
+zipStoreBase=GRADLE_USER_HOME
5
+zipStorePath=wrapper/dists
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip

+ 164
- 0
example/android/gradlew 查看文件

@@ -0,0 +1,164 @@
1
+#!/usr/bin/env bash
2
+
3
+##############################################################################
4
+##
5
+##  Gradle start up script for UN*X
6
+##
7
+##############################################################################
8
+
9
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10
+DEFAULT_JVM_OPTS=""
11
+
12
+APP_NAME="Gradle"
13
+APP_BASE_NAME=`basename "$0"`
14
+
15
+# Use the maximum available, or set MAX_FD != -1 to use that value.
16
+MAX_FD="maximum"
17
+
18
+warn ( ) {
19
+    echo "$*"
20
+}
21
+
22
+die ( ) {
23
+    echo
24
+    echo "$*"
25
+    echo
26
+    exit 1
27
+}
28
+
29
+# OS specific support (must be 'true' or 'false').
30
+cygwin=false
31
+msys=false
32
+darwin=false
33
+case "`uname`" in
34
+  CYGWIN* )
35
+    cygwin=true
36
+    ;;
37
+  Darwin* )
38
+    darwin=true
39
+    ;;
40
+  MINGW* )
41
+    msys=true
42
+    ;;
43
+esac
44
+
45
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
46
+if $cygwin ; then
47
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48
+fi
49
+
50
+# Attempt to set APP_HOME
51
+# Resolve links: $0 may be a link
52
+PRG="$0"
53
+# Need this for relative symlinks.
54
+while [ -h "$PRG" ] ; do
55
+    ls=`ls -ld "$PRG"`
56
+    link=`expr "$ls" : '.*-> \(.*\)$'`
57
+    if expr "$link" : '/.*' > /dev/null; then
58
+        PRG="$link"
59
+    else
60
+        PRG=`dirname "$PRG"`"/$link"
61
+    fi
62
+done
63
+SAVED="`pwd`"
64
+cd "`dirname \"$PRG\"`/" >&-
65
+APP_HOME="`pwd -P`"
66
+cd "$SAVED" >&-
67
+
68
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69
+
70
+# Determine the Java command to use to start the JVM.
71
+if [ -n "$JAVA_HOME" ] ; then
72
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73
+        # IBM's JDK on AIX uses strange locations for the executables
74
+        JAVACMD="$JAVA_HOME/jre/sh/java"
75
+    else
76
+        JAVACMD="$JAVA_HOME/bin/java"
77
+    fi
78
+    if [ ! -x "$JAVACMD" ] ; then
79
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80
+
81
+Please set the JAVA_HOME variable in your environment to match the
82
+location of your Java installation."
83
+    fi
84
+else
85
+    JAVACMD="java"
86
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87
+
88
+Please set the JAVA_HOME variable in your environment to match the
89
+location of your Java installation."
90
+fi
91
+
92
+# Increase the maximum file descriptors if we can.
93
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94
+    MAX_FD_LIMIT=`ulimit -H -n`
95
+    if [ $? -eq 0 ] ; then
96
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97
+            MAX_FD="$MAX_FD_LIMIT"
98
+        fi
99
+        ulimit -n $MAX_FD
100
+        if [ $? -ne 0 ] ; then
101
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
102
+        fi
103
+    else
104
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105
+    fi
106
+fi
107
+
108
+# For Darwin, add options to specify how the application appears in the dock
109
+if $darwin; then
110
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111
+fi
112
+
113
+# For Cygwin, switch paths to Windows format before running java
114
+if $cygwin ; then
115
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117
+
118
+    # We build the pattern for arguments to be converted via cygpath
119
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120
+    SEP=""
121
+    for dir in $ROOTDIRSRAW ; do
122
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
123
+        SEP="|"
124
+    done
125
+    OURCYGPATTERN="(^($ROOTDIRS))"
126
+    # Add a user-defined pattern to the cygpath arguments
127
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129
+    fi
130
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
131
+    i=0
132
+    for arg in "$@" ; do
133
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
135
+
136
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
137
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138
+        else
139
+            eval `echo args$i`="\"$arg\""
140
+        fi
141
+        i=$((i+1))
142
+    done
143
+    case $i in
144
+        (0) set -- ;;
145
+        (1) set -- "$args0" ;;
146
+        (2) set -- "$args0" "$args1" ;;
147
+        (3) set -- "$args0" "$args1" "$args2" ;;
148
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154
+    esac
155
+fi
156
+
157
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158
+function splitJvmOpts() {
159
+    JVM_OPTS=("$@")
160
+}
161
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163
+
164
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90
- 0
example/android/gradlew.bat 查看文件

@@ -0,0 +1,90 @@
1
+@if "%DEBUG%" == "" @echo off
2
+@rem ##########################################################################
3
+@rem
4
+@rem  Gradle startup script for Windows
5
+@rem
6
+@rem ##########################################################################
7
+
8
+@rem Set local scope for the variables with windows NT shell
9
+if "%OS%"=="Windows_NT" setlocal
10
+
11
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12
+set DEFAULT_JVM_OPTS=
13
+
14
+set DIRNAME=%~dp0
15
+if "%DIRNAME%" == "" set DIRNAME=.
16
+set APP_BASE_NAME=%~n0
17
+set APP_HOME=%DIRNAME%
18
+
19
+@rem Find java.exe
20
+if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+set JAVA_EXE=java.exe
23
+%JAVA_EXE% -version >NUL 2>&1
24
+if "%ERRORLEVEL%" == "0" goto init
25
+
26
+echo.
27
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+echo.
29
+echo Please set the JAVA_HOME variable in your environment to match the
30
+echo location of your Java installation.
31
+
32
+goto fail
33
+
34
+:findJavaFromJavaHome
35
+set JAVA_HOME=%JAVA_HOME:"=%
36
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+if exist "%JAVA_EXE%" goto init
39
+
40
+echo.
41
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+echo.
43
+echo Please set the JAVA_HOME variable in your environment to match the
44
+echo location of your Java installation.
45
+
46
+goto fail
47
+
48
+:init
49
+@rem Get command-line arguments, handling Windowz variants
50
+
51
+if not "%OS%" == "Windows_NT" goto win9xME_args
52
+if "%@eval[2+2]" == "4" goto 4NT_args
53
+
54
+:win9xME_args
55
+@rem Slurp the command line arguments.
56
+set CMD_LINE_ARGS=
57
+set _SKIP=2
58
+
59
+:win9xME_args_slurp
60
+if "x%~1" == "x" goto execute
61
+
62
+set CMD_LINE_ARGS=%*
63
+goto execute
64
+
65
+:4NT_args
66
+@rem Get arguments from the 4NT Shell from JP Software
67
+set CMD_LINE_ARGS=%$
68
+
69
+:execute
70
+@rem Setup the command line
71
+
72
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73
+
74
+@rem Execute Gradle
75
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76
+
77
+:end
78
+@rem End local scope for the variables with windows NT shell
79
+if "%ERRORLEVEL%"=="0" goto mainEnd
80
+
81
+:fail
82
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83
+rem the _cmd.exe /c_ return code!
84
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85
+exit /b 1
86
+
87
+:mainEnd
88
+if "%OS%"=="Windows_NT" endlocal
89
+
90
+:omega

+ 8
- 0
example/android/keystores/BUCK 查看文件

@@ -0,0 +1,8 @@
1
+keystore(
2
+  name = 'debug',
3
+  store = 'debug.keystore',
4
+  properties = 'debug.keystore.properties',
5
+  visibility = [
6
+    'PUBLIC',
7
+  ],
8
+)

+ 4
- 0
example/android/keystores/debug.keystore.properties 查看文件

@@ -0,0 +1,4 @@
1
+key.store=debug.keystore
2
+key.alias=androiddebugkey
3
+key.store.password=android
4
+key.alias.password=android

+ 6
- 0
example/android/settings.gradle 查看文件

@@ -0,0 +1,6 @@
1
+rootProject.name = 'react_native_navigation_bootstrap'
2
+
3
+include ':app'
4
+include ':react-native-navigation'
5
+project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/')
6
+

+ 60
- 0
example/index.android.js 查看文件

@@ -0,0 +1,60 @@
1
+/**
2
+ * Sample React Native App
3
+ * https://github.com/facebook/react-native
4
+ * @flow
5
+ */
6
+
7
+import React, { Component } from 'react';
8
+import {
9
+    AppRegistry,
10
+    StyleSheet,
11
+    Text,
12
+    View
13
+} from 'react-native';
14
+import {Navigation} from 'react-native-navigation';
15
+
16
+class react_native_navigation_bootstrap extends Component {
17
+  render() {
18
+    return (
19
+        <View style={styles.container}>
20
+          <Text style={styles.welcome}>
21
+            Welcome to React Native!
22
+          </Text>
23
+          <Text style={styles.instructions}>
24
+            To get started, edit index.ios.js
25
+          </Text>
26
+          <Text style={styles.instructions}>
27
+            Press Cmd+R to reload,{'\n'}
28
+            Cmd+D or shake for dev menu
29
+          </Text>
30
+        </View>
31
+    );
32
+  }
33
+}
34
+
35
+const styles = StyleSheet.create({
36
+  container: {
37
+    flex: 1,
38
+    justifyContent: 'center',
39
+    alignItems: 'center',
40
+    backgroundColor: '#F5FCFF',
41
+  },
42
+  welcome: {
43
+    fontSize: 20,
44
+    textAlign: 'center',
45
+    margin: 10,
46
+  },
47
+  instructions: {
48
+    textAlign: 'center',
49
+    color: '#333333',
50
+    marginBottom: 5,
51
+  },
52
+});
53
+
54
+Navigation.registerComponent('react-native-navigation-bootstrap', () => react_native_navigation_bootstrap);
55
+Navigation.startSingleScreenApp({
56
+  screen: {
57
+    screen: 'react-native-navigation-bootstrap',
58
+    title: 'Navigation Bootstrap'
59
+  }
60
+});

+ 38
- 0
example/index.ios.js 查看文件

@@ -0,0 +1,38 @@
1
+import React, { Component } from 'react';
2
+import {
3
+  AppRegistry,
4
+  StyleSheet,
5
+  Text,
6
+  View
7
+} from 'react-native';
8
+import RichTextEditor from 'react-native-ZSSRichTextEditor'
9
+
10
+class RichTextExample extends Component {
11
+
12
+  render() {
13
+    return (
14
+      <View style={styles.container}>
15
+        <RichTextEditor
16
+          style={styles.richText}
17
+          initialHTML={'Hello <b>World</b> <p>this is a new paragraph</p>'}
18
+        />
19
+      </View>
20
+    );
21
+  }
22
+}
23
+
24
+const styles = StyleSheet.create({
25
+  container: {
26
+    flex: 1,
27
+    flexDirection: 'column',
28
+    backgroundColor: '#F5FCFF',
29
+    paddingTop: 40
30
+  },
31
+  richText: {
32
+    alignItems:'center',
33
+    justifyContent: 'center',
34
+    backgroundColor: 'transparent',
35
+  },
36
+});
37
+
38
+AppRegistry.registerComponent('example', () => RichTextExample);

+ 796
- 0
example/ios/react_native_navigation_bootstrap.xcodeproj/project.pbxproj 查看文件

@@ -0,0 +1,796 @@
1
+// !$*UTF8*$!
2
+{
3
+	archiveVersion = 1;
4
+	classes = {
5
+	};
6
+	objectVersion = 46;
7
+	objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+		00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
11
+		00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
12
+		00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
13
+		00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
14
+		00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
15
+		00E356F31AD99517003FC87E /* react_native_navigation_bootstrapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* react_native_navigation_bootstrapTests.m */; };
16
+		133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
17
+		139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
18
+		139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
19
+		13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
20
+		13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
21
+		13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
22
+		13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
23
+		140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24
+		146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
25
+		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
26
+		D857276A1DC8D47B00A26F4B /* libReact-Native-Webview-Bridge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85727691DC8D47200A26F4B /* libReact-Native-Webview-Bridge.a */; };
27
+/* End PBXBuildFile section */
28
+
29
+/* Begin PBXContainerItemProxy section */
30
+		00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {
31
+			isa = PBXContainerItemProxy;
32
+			containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
33
+			proxyType = 2;
34
+			remoteGlobalIDString = 134814201AA4EA6300B7C361;
35
+			remoteInfo = RCTActionSheet;
36
+		};
37
+		00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {
38
+			isa = PBXContainerItemProxy;
39
+			containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
40
+			proxyType = 2;
41
+			remoteGlobalIDString = 134814201AA4EA6300B7C361;
42
+			remoteInfo = RCTGeolocation;
43
+		};
44
+		00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {
45
+			isa = PBXContainerItemProxy;
46
+			containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
47
+			proxyType = 2;
48
+			remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
49
+			remoteInfo = RCTImage;
50
+		};
51
+		00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {
52
+			isa = PBXContainerItemProxy;
53
+			containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
54
+			proxyType = 2;
55
+			remoteGlobalIDString = 58B511DB1A9E6C8500147676;
56
+			remoteInfo = RCTNetwork;
57
+		};
58
+		00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {
59
+			isa = PBXContainerItemProxy;
60
+			containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
61
+			proxyType = 2;
62
+			remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
63
+			remoteInfo = RCTVibration;
64
+		};
65
+		00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
66
+			isa = PBXContainerItemProxy;
67
+			containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
68
+			proxyType = 1;
69
+			remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
70
+			remoteInfo = react_native_navigation_bootstrap;
71
+		};
72
+		139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
73
+			isa = PBXContainerItemProxy;
74
+			containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
75
+			proxyType = 2;
76
+			remoteGlobalIDString = 134814201AA4EA6300B7C361;
77
+			remoteInfo = RCTSettings;
78
+		};
79
+		139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {
80
+			isa = PBXContainerItemProxy;
81
+			containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
82
+			proxyType = 2;
83
+			remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
84
+			remoteInfo = RCTWebSocket;
85
+		};
86
+		146834031AC3E56700842450 /* PBXContainerItemProxy */ = {
87
+			isa = PBXContainerItemProxy;
88
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
89
+			proxyType = 2;
90
+			remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
91
+			remoteInfo = React;
92
+		};
93
+		78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
94
+			isa = PBXContainerItemProxy;
95
+			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
96
+			proxyType = 2;
97
+			remoteGlobalIDString = 134814201AA4EA6300B7C361;
98
+			remoteInfo = RCTLinking;
99
+		};
100
+		832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
101
+			isa = PBXContainerItemProxy;
102
+			containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
103
+			proxyType = 2;
104
+			remoteGlobalIDString = 58B5119B1A9E6C1200147676;
105
+			remoteInfo = RCTText;
106
+		};
107
+		D85727681DC8D47200A26F4B /* PBXContainerItemProxy */ = {
108
+			isa = PBXContainerItemProxy;
109
+			containerPortal = D85727641DC8D47200A26F4B /* React-Native-Webview-Bridge.xcodeproj */;
110
+			proxyType = 2;
111
+			remoteGlobalIDString = 4114DC4C1C187C3A003CD988;
112
+			remoteInfo = "React-Native-Webview-Bridge";
113
+		};
114
+/* End PBXContainerItemProxy section */
115
+
116
+/* Begin PBXFileReference section */
117
+		008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
118
+		00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
119
+		00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; };
120
+		00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
121
+		00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
122
+		00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
123
+		00E356EE1AD99517003FC87E /* react_native_navigation_bootstrapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = react_native_navigation_bootstrapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
124
+		00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
125
+		00E356F21AD99517003FC87E /* react_native_navigation_bootstrapTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = react_native_navigation_bootstrapTests.m; sourceTree = "<group>"; };
126
+		139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
127
+		139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
128
+		13B07F961A680F5B00A75B9A /* react_native_navigation_bootstrap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = react_native_navigation_bootstrap.app; sourceTree = BUILT_PRODUCTS_DIR; };
129
+		13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = react_native_navigation_bootstrap/AppDelegate.h; sourceTree = "<group>"; };
130
+		13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = react_native_navigation_bootstrap/AppDelegate.m; sourceTree = "<group>"; };
131
+		13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
132
+		13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = react_native_navigation_bootstrap/Images.xcassets; sourceTree = "<group>"; };
133
+		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = react_native_navigation_bootstrap/Info.plist; sourceTree = "<group>"; };
134
+		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = react_native_navigation_bootstrap/main.m; sourceTree = "<group>"; };
135
+		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
136
+		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
137
+		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
138
+		D85727641DC8D47200A26F4B /* React-Native-Webview-Bridge.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "React-Native-Webview-Bridge.xcodeproj"; path = "../node_modules/react-native-webview-bridge-updated/ios/React-Native-Webview-Bridge.xcodeproj"; sourceTree = "<group>"; };
139
+/* End PBXFileReference section */
140
+
141
+/* Begin PBXFrameworksBuildPhase section */
142
+		00E356EB1AD99517003FC87E /* Frameworks */ = {
143
+			isa = PBXFrameworksBuildPhase;
144
+			buildActionMask = 2147483647;
145
+			files = (
146
+				140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */,
147
+			);
148
+			runOnlyForDeploymentPostprocessing = 0;
149
+		};
150
+		13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
151
+			isa = PBXFrameworksBuildPhase;
152
+			buildActionMask = 2147483647;
153
+			files = (
154
+				D857276A1DC8D47B00A26F4B /* libReact-Native-Webview-Bridge.a in Frameworks */,
155
+				146834051AC3E58100842450 /* libReact.a in Frameworks */,
156
+				00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
157
+				00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
158
+				00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
159
+				133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
160
+				00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
161
+				139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
162
+				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
163
+				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
164
+				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
165
+			);
166
+			runOnlyForDeploymentPostprocessing = 0;
167
+		};
168
+/* End PBXFrameworksBuildPhase section */
169
+
170
+/* Begin PBXGroup section */
171
+		00C302A81ABCB8CE00DB3ED1 /* Products */ = {
172
+			isa = PBXGroup;
173
+			children = (
174
+				00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
175
+			);
176
+			name = Products;
177
+			sourceTree = "<group>";
178
+		};
179
+		00C302B61ABCB90400DB3ED1 /* Products */ = {
180
+			isa = PBXGroup;
181
+			children = (
182
+				00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
183
+			);
184
+			name = Products;
185
+			sourceTree = "<group>";
186
+		};
187
+		00C302BC1ABCB91800DB3ED1 /* Products */ = {
188
+			isa = PBXGroup;
189
+			children = (
190
+				00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
191
+			);
192
+			name = Products;
193
+			sourceTree = "<group>";
194
+		};
195
+		00C302D41ABCB9D200DB3ED1 /* Products */ = {
196
+			isa = PBXGroup;
197
+			children = (
198
+				00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
199
+			);
200
+			name = Products;
201
+			sourceTree = "<group>";
202
+		};
203
+		00C302E01ABCB9EE00DB3ED1 /* Products */ = {
204
+			isa = PBXGroup;
205
+			children = (
206
+				00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
207
+			);
208
+			name = Products;
209
+			sourceTree = "<group>";
210
+		};
211
+		00E356EF1AD99517003FC87E /* react_native_navigation_bootstrapTests */ = {
212
+			isa = PBXGroup;
213
+			children = (
214
+				00E356F21AD99517003FC87E /* react_native_navigation_bootstrapTests.m */,
215
+				00E356F01AD99517003FC87E /* Supporting Files */,
216
+			);
217
+			path = react_native_navigation_bootstrapTests;
218
+			sourceTree = "<group>";
219
+		};
220
+		00E356F01AD99517003FC87E /* Supporting Files */ = {
221
+			isa = PBXGroup;
222
+			children = (
223
+				00E356F11AD99517003FC87E /* Info.plist */,
224
+			);
225
+			name = "Supporting Files";
226
+			sourceTree = "<group>";
227
+		};
228
+		139105B71AF99BAD00B5F7CC /* Products */ = {
229
+			isa = PBXGroup;
230
+			children = (
231
+				139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
232
+			);
233
+			name = Products;
234
+			sourceTree = "<group>";
235
+		};
236
+		139FDEE71B06529A00C62182 /* Products */ = {
237
+			isa = PBXGroup;
238
+			children = (
239
+				139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
240
+			);
241
+			name = Products;
242
+			sourceTree = "<group>";
243
+		};
244
+		13B07FAE1A68108700A75B9A /* react_native_navigation_bootstrap */ = {
245
+			isa = PBXGroup;
246
+			children = (
247
+				008F07F21AC5B25A0029DE68 /* main.jsbundle */,
248
+				13B07FAF1A68108700A75B9A /* AppDelegate.h */,
249
+				13B07FB01A68108700A75B9A /* AppDelegate.m */,
250
+				13B07FB51A68108700A75B9A /* Images.xcassets */,
251
+				13B07FB61A68108700A75B9A /* Info.plist */,
252
+				13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
253
+				13B07FB71A68108700A75B9A /* main.m */,
254
+			);
255
+			name = react_native_navigation_bootstrap;
256
+			sourceTree = "<group>";
257
+		};
258
+		146834001AC3E56700842450 /* Products */ = {
259
+			isa = PBXGroup;
260
+			children = (
261
+				146834041AC3E56700842450 /* libReact.a */,
262
+			);
263
+			name = Products;
264
+			sourceTree = "<group>";
265
+		};
266
+		78C398B11ACF4ADC00677621 /* Products */ = {
267
+			isa = PBXGroup;
268
+			children = (
269
+				78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
270
+			);
271
+			name = Products;
272
+			sourceTree = "<group>";
273
+		};
274
+		832341AE1AAA6A7D00B99B32 /* Libraries */ = {
275
+			isa = PBXGroup;
276
+			children = (
277
+				D85727641DC8D47200A26F4B /* React-Native-Webview-Bridge.xcodeproj */,
278
+				146833FF1AC3E56700842450 /* React.xcodeproj */,
279
+				00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
280
+				00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
281
+				00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
282
+				78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
283
+				00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
284
+				139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
285
+				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
286
+				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
287
+				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
288
+			);
289
+			name = Libraries;
290
+			sourceTree = "<group>";
291
+		};
292
+		832341B11AAA6A8300B99B32 /* Products */ = {
293
+			isa = PBXGroup;
294
+			children = (
295
+				832341B51AAA6A8300B99B32 /* libRCTText.a */,
296
+			);
297
+			name = Products;
298
+			sourceTree = "<group>";
299
+		};
300
+		83CBB9F61A601CBA00E9B192 = {
301
+			isa = PBXGroup;
302
+			children = (
303
+				13B07FAE1A68108700A75B9A /* react_native_navigation_bootstrap */,
304
+				832341AE1AAA6A7D00B99B32 /* Libraries */,
305
+				00E356EF1AD99517003FC87E /* react_native_navigation_bootstrapTests */,
306
+				83CBBA001A601CBA00E9B192 /* Products */,
307
+			);
308
+			indentWidth = 2;
309
+			sourceTree = "<group>";
310
+			tabWidth = 2;
311
+		};
312
+		83CBBA001A601CBA00E9B192 /* Products */ = {
313
+			isa = PBXGroup;
314
+			children = (
315
+				13B07F961A680F5B00A75B9A /* react_native_navigation_bootstrap.app */,
316
+				00E356EE1AD99517003FC87E /* react_native_navigation_bootstrapTests.xctest */,
317
+			);
318
+			name = Products;
319
+			sourceTree = "<group>";
320
+		};
321
+		D85727651DC8D47200A26F4B /* Products */ = {
322
+			isa = PBXGroup;
323
+			children = (
324
+				D85727691DC8D47200A26F4B /* libReact-Native-Webview-Bridge.a */,
325
+			);
326
+			name = Products;
327
+			sourceTree = "<group>";
328
+		};
329
+/* End PBXGroup section */
330
+
331
+/* Begin PBXNativeTarget section */
332
+		00E356ED1AD99517003FC87E /* react_native_navigation_bootstrapTests */ = {
333
+			isa = PBXNativeTarget;
334
+			buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "react_native_navigation_bootstrapTests" */;
335
+			buildPhases = (
336
+				00E356EA1AD99517003FC87E /* Sources */,
337
+				00E356EB1AD99517003FC87E /* Frameworks */,
338
+				00E356EC1AD99517003FC87E /* Resources */,
339
+			);
340
+			buildRules = (
341
+			);
342
+			dependencies = (
343
+				00E356F51AD99517003FC87E /* PBXTargetDependency */,
344
+			);
345
+			name = react_native_navigation_bootstrapTests;
346
+			productName = react_native_navigation_bootstrapTests;
347
+			productReference = 00E356EE1AD99517003FC87E /* react_native_navigation_bootstrapTests.xctest */;
348
+			productType = "com.apple.product-type.bundle.unit-test";
349
+		};
350
+		13B07F861A680F5B00A75B9A /* react_native_navigation_bootstrap */ = {
351
+			isa = PBXNativeTarget;
352
+			buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "react_native_navigation_bootstrap" */;
353
+			buildPhases = (
354
+				13B07F871A680F5B00A75B9A /* Sources */,
355
+				13B07F8C1A680F5B00A75B9A /* Frameworks */,
356
+				13B07F8E1A680F5B00A75B9A /* Resources */,
357
+				00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
358
+			);
359
+			buildRules = (
360
+			);
361
+			dependencies = (
362
+			);
363
+			name = react_native_navigation_bootstrap;
364
+			productName = "Hello World";
365
+			productReference = 13B07F961A680F5B00A75B9A /* react_native_navigation_bootstrap.app */;
366
+			productType = "com.apple.product-type.application";
367
+		};
368
+/* End PBXNativeTarget section */
369
+
370
+/* Begin PBXProject section */
371
+		83CBB9F71A601CBA00E9B192 /* Project object */ = {
372
+			isa = PBXProject;
373
+			attributes = {
374
+				LastUpgradeCheck = 0610;
375
+				ORGANIZATIONNAME = Facebook;
376
+				TargetAttributes = {
377
+					00E356ED1AD99517003FC87E = {
378
+						CreatedOnToolsVersion = 6.2;
379
+						TestTargetID = 13B07F861A680F5B00A75B9A;
380
+					};
381
+				};
382
+			};
383
+			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "react_native_navigation_bootstrap" */;
384
+			compatibilityVersion = "Xcode 3.2";
385
+			developmentRegion = English;
386
+			hasScannedForEncodings = 0;
387
+			knownRegions = (
388
+				en,
389
+				Base,
390
+			);
391
+			mainGroup = 83CBB9F61A601CBA00E9B192;
392
+			productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
393
+			projectDirPath = "";
394
+			projectReferences = (
395
+				{
396
+					ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
397
+					ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
398
+				},
399
+				{
400
+					ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
401
+					ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
402
+				},
403
+				{
404
+					ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
405
+					ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
406
+				},
407
+				{
408
+					ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
409
+					ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
410
+				},
411
+				{
412
+					ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
413
+					ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
414
+				},
415
+				{
416
+					ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
417
+					ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
418
+				},
419
+				{
420
+					ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
421
+					ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
422
+				},
423
+				{
424
+					ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
425
+					ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
426
+				},
427
+				{
428
+					ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
429
+					ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
430
+				},
431
+				{
432
+					ProductGroup = D85727651DC8D47200A26F4B /* Products */;
433
+					ProjectRef = D85727641DC8D47200A26F4B /* React-Native-Webview-Bridge.xcodeproj */;
434
+				},
435
+				{
436
+					ProductGroup = 146834001AC3E56700842450 /* Products */;
437
+					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
438
+				},
439
+			);
440
+			projectRoot = "";
441
+			targets = (
442
+				13B07F861A680F5B00A75B9A /* react_native_navigation_bootstrap */,
443
+				00E356ED1AD99517003FC87E /* react_native_navigation_bootstrapTests */,
444
+			);
445
+		};
446
+/* End PBXProject section */
447
+
448
+/* Begin PBXReferenceProxy section */
449
+		00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
450
+			isa = PBXReferenceProxy;
451
+			fileType = archive.ar;
452
+			path = libRCTActionSheet.a;
453
+			remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
454
+			sourceTree = BUILT_PRODUCTS_DIR;
455
+		};
456
+		00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
457
+			isa = PBXReferenceProxy;
458
+			fileType = archive.ar;
459
+			path = libRCTGeolocation.a;
460
+			remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
461
+			sourceTree = BUILT_PRODUCTS_DIR;
462
+		};
463
+		00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
464
+			isa = PBXReferenceProxy;
465
+			fileType = archive.ar;
466
+			path = libRCTImage.a;
467
+			remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
468
+			sourceTree = BUILT_PRODUCTS_DIR;
469
+		};
470
+		00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
471
+			isa = PBXReferenceProxy;
472
+			fileType = archive.ar;
473
+			path = libRCTNetwork.a;
474
+			remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
475
+			sourceTree = BUILT_PRODUCTS_DIR;
476
+		};
477
+		00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
478
+			isa = PBXReferenceProxy;
479
+			fileType = archive.ar;
480
+			path = libRCTVibration.a;
481
+			remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
482
+			sourceTree = BUILT_PRODUCTS_DIR;
483
+		};
484
+		139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
485
+			isa = PBXReferenceProxy;
486
+			fileType = archive.ar;
487
+			path = libRCTSettings.a;
488
+			remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
489
+			sourceTree = BUILT_PRODUCTS_DIR;
490
+		};
491
+		139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
492
+			isa = PBXReferenceProxy;
493
+			fileType = archive.ar;
494
+			path = libRCTWebSocket.a;
495
+			remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
496
+			sourceTree = BUILT_PRODUCTS_DIR;
497
+		};
498
+		146834041AC3E56700842450 /* libReact.a */ = {
499
+			isa = PBXReferenceProxy;
500
+			fileType = archive.ar;
501
+			path = libReact.a;
502
+			remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
503
+			sourceTree = BUILT_PRODUCTS_DIR;
504
+		};
505
+		78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
506
+			isa = PBXReferenceProxy;
507
+			fileType = archive.ar;
508
+			path = libRCTLinking.a;
509
+			remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
510
+			sourceTree = BUILT_PRODUCTS_DIR;
511
+		};
512
+		832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
513
+			isa = PBXReferenceProxy;
514
+			fileType = archive.ar;
515
+			path = libRCTText.a;
516
+			remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
517
+			sourceTree = BUILT_PRODUCTS_DIR;
518
+		};
519
+		D85727691DC8D47200A26F4B /* libReact-Native-Webview-Bridge.a */ = {
520
+			isa = PBXReferenceProxy;
521
+			fileType = archive.ar;
522
+			path = "libReact-Native-Webview-Bridge.a";
523
+			remoteRef = D85727681DC8D47200A26F4B /* PBXContainerItemProxy */;
524
+			sourceTree = BUILT_PRODUCTS_DIR;
525
+		};
526
+/* End PBXReferenceProxy section */
527
+
528
+/* Begin PBXResourcesBuildPhase section */
529
+		00E356EC1AD99517003FC87E /* Resources */ = {
530
+			isa = PBXResourcesBuildPhase;
531
+			buildActionMask = 2147483647;
532
+			files = (
533
+			);
534
+			runOnlyForDeploymentPostprocessing = 0;
535
+		};
536
+		13B07F8E1A680F5B00A75B9A /* Resources */ = {
537
+			isa = PBXResourcesBuildPhase;
538
+			buildActionMask = 2147483647;
539
+			files = (
540
+				13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
541
+				13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
542
+			);
543
+			runOnlyForDeploymentPostprocessing = 0;
544
+		};
545
+/* End PBXResourcesBuildPhase section */
546
+
547
+/* Begin PBXShellScriptBuildPhase section */
548
+		00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
549
+			isa = PBXShellScriptBuildPhase;
550
+			buildActionMask = 2147483647;
551
+			files = (
552
+			);
553
+			inputPaths = (
554
+			);
555
+			name = "Bundle React Native code and images";
556
+			outputPaths = (
557
+			);
558
+			runOnlyForDeploymentPostprocessing = 0;
559
+			shellPath = /bin/sh;
560
+			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
561
+		};
562
+/* End PBXShellScriptBuildPhase section */
563
+
564
+/* Begin PBXSourcesBuildPhase section */
565
+		00E356EA1AD99517003FC87E /* Sources */ = {
566
+			isa = PBXSourcesBuildPhase;
567
+			buildActionMask = 2147483647;
568
+			files = (
569
+				00E356F31AD99517003FC87E /* react_native_navigation_bootstrapTests.m in Sources */,
570
+			);
571
+			runOnlyForDeploymentPostprocessing = 0;
572
+		};
573
+		13B07F871A680F5B00A75B9A /* Sources */ = {
574
+			isa = PBXSourcesBuildPhase;
575
+			buildActionMask = 2147483647;
576
+			files = (
577
+				13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
578
+				13B07FC11A68108700A75B9A /* main.m in Sources */,
579
+			);
580
+			runOnlyForDeploymentPostprocessing = 0;
581
+		};
582
+/* End PBXSourcesBuildPhase section */
583
+
584
+/* Begin PBXTargetDependency section */
585
+		00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
586
+			isa = PBXTargetDependency;
587
+			target = 13B07F861A680F5B00A75B9A /* react_native_navigation_bootstrap */;
588
+			targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
589
+		};
590
+/* End PBXTargetDependency section */
591
+
592
+/* Begin PBXVariantGroup section */
593
+		13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
594
+			isa = PBXVariantGroup;
595
+			children = (
596
+				13B07FB21A68108700A75B9A /* Base */,
597
+			);
598
+			name = LaunchScreen.xib;
599
+			path = react_native_navigation_bootstrap;
600
+			sourceTree = "<group>";
601
+		};
602
+/* End PBXVariantGroup section */
603
+
604
+/* Begin XCBuildConfiguration section */
605
+		00E356F61AD99517003FC87E /* Debug */ = {
606
+			isa = XCBuildConfiguration;
607
+			buildSettings = {
608
+				BUNDLE_LOADER = "$(TEST_HOST)";
609
+				GCC_PREPROCESSOR_DEFINITIONS = (
610
+					"DEBUG=1",
611
+					"$(inherited)",
612
+				);
613
+				INFOPLIST_FILE = react_native_navigation_bootstrapTests/Info.plist;
614
+				IPHONEOS_DEPLOYMENT_TARGET = 8.2;
615
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
616
+				PRODUCT_NAME = "$(TARGET_NAME)";
617
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/react_native_navigation_bootstrap.app/react_native_navigation_bootstrap";
618
+			};
619
+			name = Debug;
620
+		};
621
+		00E356F71AD99517003FC87E /* Release */ = {
622
+			isa = XCBuildConfiguration;
623
+			buildSettings = {
624
+				BUNDLE_LOADER = "$(TEST_HOST)";
625
+				COPY_PHASE_STRIP = NO;
626
+				INFOPLIST_FILE = react_native_navigation_bootstrapTests/Info.plist;
627
+				IPHONEOS_DEPLOYMENT_TARGET = 8.2;
628
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
629
+				PRODUCT_NAME = "$(TARGET_NAME)";
630
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/react_native_navigation_bootstrap.app/react_native_navigation_bootstrap";
631
+			};
632
+			name = Release;
633
+		};
634
+		13B07F941A680F5B00A75B9A /* Debug */ = {
635
+			isa = XCBuildConfiguration;
636
+			buildSettings = {
637
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
638
+				DEAD_CODE_STRIPPING = NO;
639
+				HEADER_SEARCH_PATHS = (
640
+					"$(inherited)",
641
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
642
+					"$(SRCROOT)/../node_modules/react-native/React/**",
643
+					"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
644
+				);
645
+				INFOPLIST_FILE = react_native_navigation_bootstrap/Info.plist;
646
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
647
+				OTHER_LDFLAGS = (
648
+					"$(inherited)",
649
+					"-ObjC",
650
+					"-lc++",
651
+				);
652
+				PRODUCT_NAME = react_native_navigation_bootstrap;
653
+			};
654
+			name = Debug;
655
+		};
656
+		13B07F951A680F5B00A75B9A /* Release */ = {
657
+			isa = XCBuildConfiguration;
658
+			buildSettings = {
659
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
660
+				HEADER_SEARCH_PATHS = (
661
+					"$(inherited)",
662
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
663
+					"$(SRCROOT)/../node_modules/react-native/React/**",
664
+					"$(SRCROOT)/../node_modules/react-native-navigation/ios/**",
665
+				);
666
+				INFOPLIST_FILE = react_native_navigation_bootstrap/Info.plist;
667
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
668
+				OTHER_LDFLAGS = (
669
+					"$(inherited)",
670
+					"-ObjC",
671
+					"-lc++",
672
+				);
673
+				PRODUCT_NAME = react_native_navigation_bootstrap;
674
+			};
675
+			name = Release;
676
+		};
677
+		83CBBA201A601CBA00E9B192 /* Debug */ = {
678
+			isa = XCBuildConfiguration;
679
+			buildSettings = {
680
+				ALWAYS_SEARCH_USER_PATHS = NO;
681
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
682
+				CLANG_CXX_LIBRARY = "libc++";
683
+				CLANG_ENABLE_MODULES = YES;
684
+				CLANG_ENABLE_OBJC_ARC = YES;
685
+				CLANG_WARN_BOOL_CONVERSION = YES;
686
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
687
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
688
+				CLANG_WARN_EMPTY_BODY = YES;
689
+				CLANG_WARN_ENUM_CONVERSION = YES;
690
+				CLANG_WARN_INT_CONVERSION = YES;
691
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
692
+				CLANG_WARN_UNREACHABLE_CODE = YES;
693
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
694
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
695
+				COPY_PHASE_STRIP = NO;
696
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
697
+				GCC_C_LANGUAGE_STANDARD = gnu99;
698
+				GCC_DYNAMIC_NO_PIC = NO;
699
+				GCC_OPTIMIZATION_LEVEL = 0;
700
+				GCC_PREPROCESSOR_DEFINITIONS = (
701
+					"DEBUG=1",
702
+					"$(inherited)",
703
+				);
704
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
705
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
706
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
707
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
708
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
709
+				GCC_WARN_UNUSED_FUNCTION = YES;
710
+				GCC_WARN_UNUSED_VARIABLE = YES;
711
+				HEADER_SEARCH_PATHS = (
712
+					"$(inherited)",
713
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
714
+					"$(SRCROOT)/../node_modules/react-native/React/**",
715
+				);
716
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
717
+				MTL_ENABLE_DEBUG_INFO = YES;
718
+				ONLY_ACTIVE_ARCH = YES;
719
+				SDKROOT = iphoneos;
720
+			};
721
+			name = Debug;
722
+		};
723
+		83CBBA211A601CBA00E9B192 /* Release */ = {
724
+			isa = XCBuildConfiguration;
725
+			buildSettings = {
726
+				ALWAYS_SEARCH_USER_PATHS = NO;
727
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
728
+				CLANG_CXX_LIBRARY = "libc++";
729
+				CLANG_ENABLE_MODULES = YES;
730
+				CLANG_ENABLE_OBJC_ARC = YES;
731
+				CLANG_WARN_BOOL_CONVERSION = YES;
732
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
733
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
734
+				CLANG_WARN_EMPTY_BODY = YES;
735
+				CLANG_WARN_ENUM_CONVERSION = YES;
736
+				CLANG_WARN_INT_CONVERSION = YES;
737
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
738
+				CLANG_WARN_UNREACHABLE_CODE = YES;
739
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
740
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
741
+				COPY_PHASE_STRIP = YES;
742
+				ENABLE_NS_ASSERTIONS = NO;
743
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
744
+				GCC_C_LANGUAGE_STANDARD = gnu99;
745
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
746
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
747
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
748
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
749
+				GCC_WARN_UNUSED_FUNCTION = YES;
750
+				GCC_WARN_UNUSED_VARIABLE = YES;
751
+				HEADER_SEARCH_PATHS = (
752
+					"$(inherited)",
753
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
754
+					"$(SRCROOT)/../node_modules/react-native/React/**",
755
+				);
756
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
757
+				MTL_ENABLE_DEBUG_INFO = NO;
758
+				SDKROOT = iphoneos;
759
+				VALIDATE_PRODUCT = YES;
760
+			};
761
+			name = Release;
762
+		};
763
+/* End XCBuildConfiguration section */
764
+
765
+/* Begin XCConfigurationList section */
766
+		00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "react_native_navigation_bootstrapTests" */ = {
767
+			isa = XCConfigurationList;
768
+			buildConfigurations = (
769
+				00E356F61AD99517003FC87E /* Debug */,
770
+				00E356F71AD99517003FC87E /* Release */,
771
+			);
772
+			defaultConfigurationIsVisible = 0;
773
+			defaultConfigurationName = Release;
774
+		};
775
+		13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "react_native_navigation_bootstrap" */ = {
776
+			isa = XCConfigurationList;
777
+			buildConfigurations = (
778
+				13B07F941A680F5B00A75B9A /* Debug */,
779
+				13B07F951A680F5B00A75B9A /* Release */,
780
+			);
781
+			defaultConfigurationIsVisible = 0;
782
+			defaultConfigurationName = Release;
783
+		};
784
+		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "react_native_navigation_bootstrap" */ = {
785
+			isa = XCConfigurationList;
786
+			buildConfigurations = (
787
+				83CBBA201A601CBA00E9B192 /* Debug */,
788
+				83CBBA211A601CBA00E9B192 /* Release */,
789
+			);
790
+			defaultConfigurationIsVisible = 0;
791
+			defaultConfigurationName = Release;
792
+		};
793
+/* End XCConfigurationList section */
794
+	};
795
+	rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
796
+}

+ 112
- 0
example/ios/react_native_navigation_bootstrap.xcodeproj/xcshareddata/xcschemes/react_native_navigation_bootstrap.xcscheme 查看文件

@@ -0,0 +1,112 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+   LastUpgradeVersion = "0620"
4
+   version = "1.3">
5
+   <BuildAction
6
+      parallelizeBuildables = "YES"
7
+      buildImplicitDependencies = "YES">
8
+      <BuildActionEntries>
9
+         <BuildActionEntry
10
+            buildForTesting = "YES"
11
+            buildForRunning = "YES"
12
+            buildForProfiling = "YES"
13
+            buildForArchiving = "YES"
14
+            buildForAnalyzing = "YES">
15
+            <BuildableReference
16
+               BuildableIdentifier = "primary"
17
+               BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
18
+               BuildableName = "react_native_navigation_bootstrap.app"
19
+               BlueprintName = "react_native_navigation_bootstrap"
20
+               ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
21
+            </BuildableReference>
22
+         </BuildActionEntry>
23
+         <BuildActionEntry
24
+            buildForTesting = "YES"
25
+            buildForRunning = "YES"
26
+            buildForProfiling = "NO"
27
+            buildForArchiving = "NO"
28
+            buildForAnalyzing = "YES">
29
+            <BuildableReference
30
+               BuildableIdentifier = "primary"
31
+               BlueprintIdentifier = "00E356ED1AD99517003FC87E"
32
+               BuildableName = "react_native_navigation_bootstrapTests.xctest"
33
+               BlueprintName = "react_native_navigation_bootstrapTests"
34
+               ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
35
+            </BuildableReference>
36
+         </BuildActionEntry>
37
+      </BuildActionEntries>
38
+   </BuildAction>
39
+   <TestAction
40
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
41
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
42
+      shouldUseLaunchSchemeArgsEnv = "YES"
43
+      buildConfiguration = "Debug">
44
+      <Testables>
45
+         <TestableReference
46
+            skipped = "NO">
47
+            <BuildableReference
48
+               BuildableIdentifier = "primary"
49
+               BlueprintIdentifier = "00E356ED1AD99517003FC87E"
50
+               BuildableName = "react_native_navigation_bootstrapTests.xctest"
51
+               BlueprintName = "react_native_navigation_bootstrapTests"
52
+               ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
53
+            </BuildableReference>
54
+         </TestableReference>
55
+      </Testables>
56
+      <MacroExpansion>
57
+         <BuildableReference
58
+            BuildableIdentifier = "primary"
59
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
60
+            BuildableName = "react_native_navigation_bootstrap.app"
61
+            BlueprintName = "react_native_navigation_bootstrap"
62
+            ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
63
+         </BuildableReference>
64
+      </MacroExpansion>
65
+   </TestAction>
66
+   <LaunchAction
67
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
68
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
69
+      launchStyle = "0"
70
+      useCustomWorkingDirectory = "NO"
71
+      buildConfiguration = "Debug"
72
+      ignoresPersistentStateOnLaunch = "NO"
73
+      debugDocumentVersioning = "YES"
74
+      allowLocationSimulation = "YES">
75
+      <BuildableProductRunnable
76
+         runnableDebuggingMode = "0">
77
+         <BuildableReference
78
+            BuildableIdentifier = "primary"
79
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
80
+            BuildableName = "react_native_navigation_bootstrap.app"
81
+            BlueprintName = "react_native_navigation_bootstrap"
82
+            ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
83
+         </BuildableReference>
84
+      </BuildableProductRunnable>
85
+      <AdditionalOptions>
86
+      </AdditionalOptions>
87
+   </LaunchAction>
88
+   <ProfileAction
89
+      shouldUseLaunchSchemeArgsEnv = "YES"
90
+      savedToolIdentifier = ""
91
+      useCustomWorkingDirectory = "NO"
92
+      buildConfiguration = "Release"
93
+      debugDocumentVersioning = "YES">
94
+      <BuildableProductRunnable
95
+         runnableDebuggingMode = "0">
96
+         <BuildableReference
97
+            BuildableIdentifier = "primary"
98
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
99
+            BuildableName = "react_native_navigation_bootstrap.app"
100
+            BlueprintName = "react_native_navigation_bootstrap"
101
+            ReferencedContainer = "container:react_native_navigation_bootstrap.xcodeproj">
102
+         </BuildableReference>
103
+      </BuildableProductRunnable>
104
+   </ProfileAction>
105
+   <AnalyzeAction
106
+      buildConfiguration = "Debug">
107
+   </AnalyzeAction>
108
+   <ArchiveAction
109
+      buildConfiguration = "Release"
110
+      revealArchiveInOrganizer = "YES">
111
+   </ArchiveAction>
112
+</Scheme>

+ 16
- 0
example/ios/react_native_navigation_bootstrap/AppDelegate.h 查看文件

@@ -0,0 +1,16 @@
1
+/**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+#import <UIKit/UIKit.h>
11
+
12
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
13
+
14
+@property (nonatomic, strong) UIWindow *window;
15
+
16
+@end

+ 42
- 0
example/ios/react_native_navigation_bootstrap/AppDelegate.m 查看文件

@@ -0,0 +1,42 @@
1
+/**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+#import "AppDelegate.h"
11
+#import "RCTBundleURLProvider.h"
12
+#import "RCTRootView.h"
13
+
14
+// IMPORTANT: if you're getting an Xcode error that RCCManager.h isn't found, you've probably ran "npm install"
15
+// with npm ver 2. You'll need to "npm install" with npm 3 (see https://github.com/wix/react-native-navigation/issues/1)
16
+
17
+#import "RCTRootView.h"
18
+
19
+@implementation AppDelegate
20
+
21
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
22
+{
23
+  NSURL *jsCodeLocation;
24
+  
25
+  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
26
+  
27
+  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
28
+                                                      moduleName:@"example"
29
+                                               initialProperties:nil
30
+                                                   launchOptions:launchOptions];
31
+  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
32
+  
33
+  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
34
+  UIViewController *rootViewController = [UIViewController new];
35
+  rootViewController.view = rootView;
36
+  self.window.rootViewController = rootViewController;
37
+  [self.window makeKeyAndVisible];
38
+  
39
+  return YES;
40
+}
41
+
42
+@end

+ 42
- 0
example/ios/react_native_navigation_bootstrap/Base.lproj/LaunchScreen.xib 查看文件

@@ -0,0 +1,42 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
3
+    <dependencies>
4
+        <deployment identifier="iOS"/>
5
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
6
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
7
+    </dependencies>
8
+    <objects>
9
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
10
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
11
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
12
+            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
13
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
14
+            <subviews>
15
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
16
+                    <rect key="frame" x="20" y="439" width="441" height="21"/>
17
+                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
18
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
19
+                    <nil key="highlightedColor"/>
20
+                </label>
21
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="react_native_navigation_bootstrap" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
22
+                    <rect key="frame" x="20" y="140" width="441" height="43"/>
23
+                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
24
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
25
+                    <nil key="highlightedColor"/>
26
+                </label>
27
+            </subviews>
28
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
29
+            <constraints>
30
+                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
31
+                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
32
+                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
33
+                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
34
+                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
35
+                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
36
+            </constraints>
37
+            <nil key="simulatedStatusBarMetrics"/>
38
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
39
+            <point key="canvasLocation" x="548" y="455"/>
40
+        </view>
41
+    </objects>
42
+</document>

+ 38
- 0
example/ios/react_native_navigation_bootstrap/Images.xcassets/AppIcon.appiconset/Contents.json 查看文件

@@ -0,0 +1,38 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "iphone",
5
+      "size" : "29x29",
6
+      "scale" : "2x"
7
+    },
8
+    {
9
+      "idiom" : "iphone",
10
+      "size" : "29x29",
11
+      "scale" : "3x"
12
+    },
13
+    {
14
+      "idiom" : "iphone",
15
+      "size" : "40x40",
16
+      "scale" : "2x"
17
+    },
18
+    {
19
+      "idiom" : "iphone",
20
+      "size" : "40x40",
21
+      "scale" : "3x"
22
+    },
23
+    {
24
+      "idiom" : "iphone",
25
+      "size" : "60x60",
26
+      "scale" : "2x"
27
+    },
28
+    {
29
+      "idiom" : "iphone",
30
+      "size" : "60x60",
31
+      "scale" : "3x"
32
+    }
33
+  ],
34
+  "info" : {
35
+    "version" : 1,
36
+    "author" : "xcode"
37
+  }
38
+}

+ 55
- 0
example/ios/react_native_navigation_bootstrap/Info.plist 查看文件

@@ -0,0 +1,55 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIdentifier</key>
10
+	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11
+	<key>CFBundleInfoDictionaryVersion</key>
12
+	<string>6.0</string>
13
+	<key>CFBundleName</key>
14
+	<string>$(PRODUCT_NAME)</string>
15
+	<key>CFBundlePackageType</key>
16
+	<string>APPL</string>
17
+	<key>CFBundleShortVersionString</key>
18
+	<string>1.0</string>
19
+	<key>CFBundleSignature</key>
20
+	<string>????</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+	<key>LSRequiresIPhoneOS</key>
24
+	<true/>
25
+	<key>NSAppTransportSecurity</key>
26
+	<dict>
27
+		<key>NSAllowsArbitraryLoads</key>
28
+		<true/>
29
+		<key>NSExceptionDomains</key>
30
+		<dict>
31
+			<key>localhost</key>
32
+			<dict>
33
+				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
34
+				<true/>
35
+			</dict>
36
+		</dict>
37
+	</dict>
38
+	<key>NSLocationWhenInUseUsageDescription</key>
39
+	<string></string>
40
+	<key>UILaunchStoryboardName</key>
41
+	<string>LaunchScreen</string>
42
+	<key>UIRequiredDeviceCapabilities</key>
43
+	<array>
44
+		<string>armv7</string>
45
+	</array>
46
+	<key>UISupportedInterfaceOrientations</key>
47
+	<array>
48
+		<string>UIInterfaceOrientationPortrait</string>
49
+		<string>UIInterfaceOrientationLandscapeLeft</string>
50
+		<string>UIInterfaceOrientationLandscapeRight</string>
51
+	</array>
52
+	<key>UIViewControllerBasedStatusBarAppearance</key>
53
+	<false/>
54
+</dict>
55
+</plist>

+ 18
- 0
example/ios/react_native_navigation_bootstrap/main.m 查看文件

@@ -0,0 +1,18 @@
1
+/**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+#import <UIKit/UIKit.h>
11
+
12
+#import "AppDelegate.h"
13
+
14
+int main(int argc, char * argv[]) {
15
+  @autoreleasepool {
16
+    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17
+  }
18
+}

+ 24
- 0
example/ios/react_native_navigation_bootstrapTests/Info.plist 查看文件

@@ -0,0 +1,24 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIdentifier</key>
10
+	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11
+	<key>CFBundleInfoDictionaryVersion</key>
12
+	<string>6.0</string>
13
+	<key>CFBundleName</key>
14
+	<string>$(PRODUCT_NAME)</string>
15
+	<key>CFBundlePackageType</key>
16
+	<string>BNDL</string>
17
+	<key>CFBundleShortVersionString</key>
18
+	<string>1.0</string>
19
+	<key>CFBundleSignature</key>
20
+	<string>????</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+</dict>
24
+</plist>

+ 70
- 0
example/ios/react_native_navigation_bootstrapTests/react_native_navigation_bootstrapTests.m 查看文件

@@ -0,0 +1,70 @@
1
+/**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+#import <UIKit/UIKit.h>
11
+#import <XCTest/XCTest.h>
12
+
13
+#import "RCTLog.h"
14
+#import "RCTRootView.h"
15
+
16
+#define TIMEOUT_SECONDS 600
17
+#define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18
+
19
+@interface react_native_navigation_bootstrapTests : XCTestCase
20
+
21
+@end
22
+
23
+@implementation react_native_navigation_bootstrapTests
24
+
25
+- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26
+{
27
+  if (test(view)) {
28
+    return YES;
29
+  }
30
+  for (UIView *subview in [view subviews]) {
31
+    if ([self findSubviewInView:subview matching:test]) {
32
+      return YES;
33
+    }
34
+  }
35
+  return NO;
36
+}
37
+
38
+- (void)testRendersWelcomeScreen
39
+{
40
+  UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
41
+  NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42
+  BOOL foundElement = NO;
43
+
44
+  __block NSString *redboxError = nil;
45
+  RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46
+    if (level >= RCTLogLevelError) {
47
+      redboxError = message;
48
+    }
49
+  });
50
+
51
+  while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52
+    [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53
+    [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54
+
55
+    foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56
+      if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57
+        return YES;
58
+      }
59
+      return NO;
60
+    }];
61
+  }
62
+
63
+  RCTSetLogFunction(RCTDefaultLogFunction);
64
+
65
+  XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66
+  XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67
+}
68
+
69
+
70
+@end

+ 13
- 0
example/package.json 查看文件

@@ -0,0 +1,13 @@
1
+{
2
+  "name": "example",
3
+  "version": "0.0.1",
4
+  "private": true,
5
+  "scripts": {
6
+    "start": "react-native start"
7
+  },
8
+  "dependencies": {
9
+    "react": "15.2.1",
10
+    "react-native": "0.31.0",
11
+    "react-native-ZSSRichTextEditor": "file:../"
12
+  }
13
+}

+ 2
- 0
index.js 查看文件

@@ -0,0 +1,2 @@
1
+import RichTextEditor from './src/RichTextEditor';
2
+export default RichTextEditor;

+ 22
- 0
package.json 查看文件

@@ -0,0 +1,22 @@
1
+{
2
+  "name": "react-native-ZSSRichTextEditor",
3
+  "publishConfig": {
4
+    "registry": "https://registry.npmjs.org/"
5
+  },
6
+  "repository": {
7
+    "type": "git",
8
+    "url": "https://github.com/wix-private/react-native-ZSSRichTextEditor.git"
9
+  },
10
+  "version": "1.0.0",
11
+  "description": "React Native Wrapper for ZSSRichTextEditor",
12
+  "main": "index.js",
13
+  "private": true,
14
+  "license": "MIT",
15
+  "dependencies": {
16
+    "react-native-webview-bridge-updated": "^1.0.0"
17
+  },
18
+  "peerDependencies": {
19
+    "react": "^15.2.1",
20
+    "react-native": "^0.31.0"
21
+  }
22
+}

+ 152
- 0
src/RichTextEditor.js 查看文件

@@ -0,0 +1,152 @@
1
+import React, {Component, PropTypes} from 'react';
2
+import WebViewBridge from 'react-native-webview-bridge-updated';
3
+import {InjectedMessageHandler} from './WebviewMessageHandler';
4
+import {actions} from './const';
5
+
6
+const injectScript = `
7
+  (function () {
8
+    ${InjectedMessageHandler}
9
+  }());
10
+`;
11
+
12
+export default class RichTextEditor extends Component {
13
+  static propTypes = {
14
+    initialHTML: PropTypes.string
15
+  };
16
+
17
+  constructor(props) {
18
+    super(props);
19
+    this._sendAction = this._sendAction.bind(this);
20
+  }
21
+
22
+  componentDidMount() {
23
+    setTimeout(() => {
24
+      this.setHTML(this.props.initialHTML);
25
+    }, 1000);
26
+  }
27
+
28
+  onBridgeMessage(message){
29
+    console.log('RichTextEditor', 'bridge message: ', message);
30
+  }
31
+
32
+  onShouldStartLoadRequest(event) {
33
+    console.log('RichTextEditor', 'should start load request event: ', event);
34
+    return (event.url.indexOf("editor.html") != -1);
35
+  }
36
+
37
+  render() {
38
+    return (
39
+      <WebViewBridge
40
+        {...this.props}
41
+        hideKeyboardAccessoryView={true}
42
+        ref={(r) => {this.webviewBridge = r}}
43
+        onBridgeMessage={(message) => this.onBridgeMessage(message)}
44
+        onShouldStartLoadWithRequest={(event) => this.onShouldStartLoadRequest(event)}
45
+        source={require('./editor.html')}
46
+        injectedJavaScript={injectScript}
47
+      />
48
+    );
49
+  }
50
+
51
+  //-------------------------------------------------------------------------------
52
+  //--------------- Public API
53
+
54
+  _sendAction(action, data) {
55
+    this.webviewBridge.sendToBridge(JSON.stringify({type: action, data}));
56
+  }
57
+
58
+  setHTML(html) {
59
+    this._sendAction(actions.setHtml, html);
60
+  }
61
+
62
+  blurEditor() {
63
+    this.refs.webviewbridge.sendToBridge(`zss_editor.blurEditor();`);
64
+  }
65
+
66
+  setBold() {
67
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setBold();`);
68
+  }
69
+
70
+  setItalic() {
71
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setItalic();`);
72
+  }
73
+
74
+  setUnderline() {
75
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setUnderline();`);
76
+  }
77
+
78
+  heading1() {
79
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h1');`);
80
+  }
81
+
82
+  heading2() {
83
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h2');`);
84
+  }
85
+
86
+  heading3() {
87
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h3');`);
88
+  }
89
+
90
+  heading4() {
91
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h4');`);
92
+  }
93
+
94
+  heading5() {
95
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h5');`);
96
+  }
97
+
98
+  heading6() {
99
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHeading('h6');`);
100
+  }
101
+
102
+  setParagraph() {
103
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setParagraph();`);
104
+  }
105
+
106
+  removeFormat() {
107
+    this.refs.webviewbridge.sendToBridge(`zss_editor.removeFormating();`);
108
+  }
109
+
110
+  alignLeft() {
111
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setJustifyLeft();`);
112
+  }
113
+
114
+  alignCenter() {
115
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setJustifyCenter();`);
116
+  }
117
+
118
+  alignRight() {
119
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setJustifyRight();`);
120
+  }
121
+
122
+  alignFull() {
123
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setJustifyFull();`);
124
+  }
125
+
126
+  insertBulletsList() {
127
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setUnorderedList();`);
128
+  }
129
+
130
+  insertOrderedList() {
131
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setOrderedList();`);
132
+  }
133
+
134
+  setSubscript() {
135
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setSubscript();`);
136
+  }
137
+  setSuperscript() {
138
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setSuperscript();`);
139
+  }
140
+  setStrikethrough() {
141
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setStrikeThrough();`);
142
+  }
143
+  setHR() {
144
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setHorizontalRule();`);
145
+  }
146
+  setIndent() {
147
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setIndent();`);
148
+  }
149
+  setOutdent() {
150
+    this.refs.webviewbridge.sendToBridge(`zss_editor.setOutdent();`);
151
+  }
152
+}

+ 14
- 0
src/WebviewMessageHandler.js 查看文件

@@ -0,0 +1,14 @@
1
+import {actions} from './const';
2
+
3
+export const InjectedMessageHandler = `
4
+  if (WebViewBridge) {
5
+    WebViewBridge.onMessage = function (message) {
6
+      const action = JSON.parse(message);
7
+      switch(action.type) {
8
+        case '${actions.setHtml}':
9
+          zss_editor.setHTML(action.data);
10
+          break;
11
+      }
12
+    };
13
+  }
14
+`;

+ 766
- 0
src/ZSSRichTextEditor/JSBeautifier.js 查看文件

@@ -0,0 +1,766 @@
1
+/*
2
+ 
3
+ The MIT License (MIT)
4
+ 
5
+ Copyright (c) 2007-2013 Einar Lielmanis and contributors.
6
+ 
7
+ Permission is hereby granted, free of charge, to any person
8
+ obtaining a copy of this software and associated documentation files
9
+ (the "Software"), to deal in the Software without restriction,
10
+ including without limitation the rights to use, copy, modify, merge,
11
+ publish, distribute, sublicense, and/or sell copies of the Software,
12
+ and to permit persons to whom the Software is furnished to do so,
13
+ subject to the following conditions:
14
+ 
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+ 
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+ 
27
+ JS Beautifier
28
+ ---------------
29
+ 
30
+ */
31
+
32
+function trim(s) {
33
+	return s.replace(/^\s+|\s+$/g, '');
34
+}
35
+
36
+function ltrim(s) {
37
+	return s.replace(/^\s+/g, '');
38
+}
39
+
40
+function style_html(html_source, options) {
41
+	//Wrapper function to invoke all the necessary constructors and deal with the output.
42
+
43
+	var multi_parser,
44
+		indent_inner_html,
45
+		indent_size,
46
+		indent_character,
47
+		wrap_line_length,
48
+		brace_style,
49
+		unformatted,
50
+		preserve_newlines,
51
+		max_preserve_newlines;
52
+
53
+	options = options || {};
54
+
55
+	// backwards compatibility to 1.3.4
56
+	if ((options.wrap_line_length === undefined || parseInt(options.wrap_line_length, 10) === 0) &&
57
+			(options.max_char === undefined || parseInt(options.max_char, 10) === 0)) {
58
+		options.wrap_line_length = options.max_char;
59
+	}
60
+
61
+	indent_inner_html = options.indent_inner_html || false;
62
+	indent_size = parseInt(options.indent_size || 4, 10);
63
+	indent_character = options.indent_char || ' ';
64
+	brace_style = options.brace_style || 'collapse';
65
+	wrap_line_length =  parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10);
66
+	unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
67
+	preserve_newlines = options.preserve_newlines || true;
68
+	max_preserve_newlines = preserve_newlines ? parseInt(options.max_preserve_newlines || 32786, 10) : 0;
69
+	indent_handlebars = options.indent_handlebars || false;
70
+
71
+	function Parser() {
72
+
73
+		this.pos = 0; //Parser position
74
+		this.token = '';
75
+		this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
76
+		this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
77
+			parent: 'parent1',
78
+			parentcount: 1,
79
+			parent1: ''
80
+		};
81
+		this.tag_type = '';
82
+		this.token_text = this.last_token = this.last_text = this.token_type = '';
83
+		this.newlines = 0;
84
+		this.indent_content = indent_inner_html;
85
+
86
+		this.Utils = { //Uilities made available to the various functions
87
+			whitespace: "\n\r\t ".split(''),
88
+			single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
89
+			extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
90
+			in_array: function(what, arr) {
91
+				for (var i = 0; i < arr.length; i++) {
92
+					if (what === arr[i]) {
93
+						return true;
94
+					}
95
+				}
96
+				return false;
97
+			}
98
+		};
99
+
100
+		this.traverse_whitespace = function() {
101
+			var input_char = '';
102
+
103
+			input_char = this.input.charAt(this.pos);
104
+			if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
105
+				this.newlines = 0;
106
+				while (this.Utils.in_array(input_char, this.Utils.whitespace)) {
107
+					if (preserve_newlines && input_char === '\n' && this.newlines <= max_preserve_newlines) {
108
+						this.newlines += 1;
109
+					}
110
+
111
+					this.pos++;
112
+					input_char = this.input.charAt(this.pos);
113
+				}
114
+				return true;
115
+			}
116
+			return false;
117
+		};
118
+
119
+		this.get_content = function() { //function to capture regular content between tags
120
+
121
+			var input_char = '',
122
+				content = [],
123
+				space = false; //if a space is needed
124
+
125
+			while (this.input.charAt(this.pos) !== '<') {
126
+				if (this.pos >= this.input.length) {
127
+					return content.length ? content.join('') : ['', 'TK_EOF'];
128
+				}
129
+
130
+				if (this.traverse_whitespace()) {
131
+					if (content.length) {
132
+						space = true;
133
+					}
134
+					continue; //don't want to insert unnecessary space
135
+				}
136
+
137
+				if (indent_handlebars) {
138
+					// Handlebars parsing is complicated.
139
+					// {{#foo}} and {{/foo}} are formatted tags.
140
+					// {{something}} should get treated as content, except:
141
+					// {{else}} specifically behaves like {{#if}} and {{/if}}
142
+					var peek3 = this.input.substr(this.pos, 3);
143
+					if (peek3 === '{{#' || peek3 === '{{/') {
144
+						// These are tags and not content.
145
+						break;
146
+					} else if (this.input.substr(this.pos, 2) === '{{') {
147
+						if (this.get_tag(true) === '{{else}}') {
148
+							break;
149
+						}
150
+					}
151
+				}
152
+
153
+				input_char = this.input.charAt(this.pos);
154
+				this.pos++;
155
+
156
+				if (space) {
157
+					if (this.line_char_count >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached
158
+						this.print_newline(false, content);
159
+						this.print_indentation(content);
160
+					} else {
161
+						this.line_char_count++;
162
+						content.push(' ');
163
+					}
164
+					space = false;
165
+				}
166
+				this.line_char_count++;
167
+				content.push(input_char); //letter at-a-time (or string) inserted to an array
168
+			}
169
+			return content.length ? content.join('') : '';
170
+		};
171
+
172
+		this.get_contents_to = function(name) { //get the full content of a script or style to pass to js_beautify
173
+			if (this.pos === this.input.length) {
174
+				return ['', 'TK_EOF'];
175
+			}
176
+			var input_char = '';
177
+			var content = '';
178
+			var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
179
+			reg_match.lastIndex = this.pos;
180
+			var reg_array = reg_match.exec(this.input);
181
+			var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script
182
+			if (this.pos < end_script) { //get everything in between the script tags
183
+				content = this.input.substring(this.pos, end_script);
184
+				this.pos = end_script;
185
+			}
186
+			return content;
187
+		};
188
+
189
+		this.record_tag = function(tag) { //function to record a tag and its parent in this.tags Object
190
+			if (this.tags[tag + 'count']) { //check for the existence of this tag type
191
+				this.tags[tag + 'count']++;
192
+				this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
193
+			} else { //otherwise initialize this tag type
194
+				this.tags[tag + 'count'] = 1;
195
+				this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
196
+			}
197
+			this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
198
+			this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
199
+		};
200
+
201
+		this.retrieve_tag = function(tag) { //function to retrieve the opening tag to the corresponding closer
202
+			if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
203
+				var temp_parent = this.tags.parent; //check to see if it's a closable tag.
204
+				while (temp_parent) { //till we reach '' (the initial value);
205
+					if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
206
+						break;
207
+					}
208
+					temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
209
+				}
210
+				if (temp_parent) { //if we caught something
211
+					this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
212
+					this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
213
+				}
214
+				delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
215
+				delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
216
+				if (this.tags[tag + 'count'] === 1) {
217
+					delete this.tags[tag + 'count'];
218
+				} else {
219
+					this.tags[tag + 'count']--;
220
+				}
221
+			}
222
+		};
223
+
224
+		this.indent_to_tag = function(tag) {
225
+			// Match the indentation level to the last use of this tag, but don't remove it.
226
+			if (!this.tags[tag + 'count']) {
227
+				return;
228
+			}
229
+			var temp_parent = this.tags.parent;
230
+			while (temp_parent) {
231
+				if (tag + this.tags[tag + 'count'] === temp_parent) {
232
+					break;
233
+				}
234
+				temp_parent = this.tags[temp_parent + 'parent'];
235
+			}
236
+			if (temp_parent) {
237
+				this.indent_level = this.tags[tag + this.tags[tag + 'count']];
238
+			}
239
+		};
240
+
241
+		this.get_tag = function(peek) { //function to get a full tag and parse its type
242
+			var input_char = '',
243
+				content = [],
244
+				comment = '',
245
+				space = false,
246
+				tag_start, tag_end,
247
+				tag_start_char,
248
+				orig_pos = this.pos,
249
+				orig_line_char_count = this.line_char_count;
250
+
251
+			peek = peek !== undefined ? peek : false;
252
+
253
+			do {
254
+				if (this.pos >= this.input.length) {
255
+					if (peek) {
256
+						this.pos = orig_pos;
257
+						this.line_char_count = orig_line_char_count;
258
+					}
259
+					return content.length ? content.join('') : ['', 'TK_EOF'];
260
+				}
261
+
262
+				input_char = this.input.charAt(this.pos);
263
+				this.pos++;
264
+
265
+				if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
266
+					space = true;
267
+					continue;
268
+				}
269
+
270
+				if (input_char === "'" || input_char === '"') {
271
+					input_char += this.get_unformatted(input_char);
272
+					space = true;
273
+
274
+				}
275
+
276
+				if (input_char === '=') { //no space before =
277
+					space = false;
278
+				}
279
+
280
+				if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space) {
281
+					//no space after = or before >
282
+					if (this.line_char_count >= this.wrap_line_length) {
283
+						this.print_newline(false, content);
284
+						this.print_indentation(content);
285
+					} else {
286
+						content.push(' ');
287
+						this.line_char_count++;
288
+					}
289
+					space = false;
290
+				}
291
+
292
+				if (indent_handlebars && tag_start_char === '<') {
293
+					// When inside an angle-bracket tag, put spaces around
294
+					// handlebars not inside of strings.
295
+					if ((input_char + this.input.charAt(this.pos)) === '{{') {
296
+						input_char += this.get_unformatted('}}');
297
+						if (content.length && content[content.length - 1] !== ' ' && content[content.length - 1] !== '<') {
298
+							input_char = ' ' + input_char;
299
+						}
300
+						space = true;
301
+					}
302
+				}
303
+
304
+				if (input_char === '<' && !tag_start_char) {
305
+					tag_start = this.pos - 1;
306
+					tag_start_char = '<';
307
+				}
308
+
309
+				if (indent_handlebars && !tag_start_char) {
310
+					if (content.length >= 2 && content[content.length - 1] === '{' && content[content.length - 2] == '{') {
311
+						if (input_char === '#' || input_char === '/') {
312
+							tag_start = this.pos - 3;
313
+						} else {
314
+							tag_start = this.pos - 2;
315
+						}
316
+						tag_start_char = '{';
317
+					}
318
+				}
319
+
320
+				this.line_char_count++;
321
+				content.push(input_char); //inserts character at-a-time (or string)
322
+
323
+				if (content[1] && content[1] === '!') { //if we're in a comment, do something special
324
+					// We treat all comments as literals, even more than preformatted tags
325
+					// we just look for the appropriate close tag
326
+					content = [this.get_comment(tag_start)];
327
+					break;
328
+				}
329
+
330
+				if (indent_handlebars && tag_start_char === '{' && content.length > 2 && content[content.length - 2] === '}' && content[content.length - 1] === '}') {
331
+					break;
332
+				}
333
+			} while (input_char !== '>');
334
+
335
+			var tag_complete = content.join('');
336
+			var tag_index;
337
+			var tag_offset;
338
+
339
+			if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
340
+				tag_index = tag_complete.indexOf(' ');
341
+			} else if (tag_complete[0] === '{') {
342
+				tag_index = tag_complete.indexOf('}');
343
+			} else { //otherwise go with the tag ending
344
+				tag_index = tag_complete.indexOf('>');
345
+			}
346
+			if (tag_complete[0] === '<' || !indent_handlebars) {
347
+				tag_offset = 1;
348
+			} else {
349
+				tag_offset = tag_complete[2] === '#' ? 3 : 2;
350
+			}
351
+			var tag_check = tag_complete.substring(tag_offset, tag_index).toLowerCase();
352
+			if (tag_complete.charAt(tag_complete.length - 2) === '/' ||
353
+				this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
354
+				if (!peek) {
355
+					this.tag_type = 'SINGLE';
356
+				}
357
+			} else if (indent_handlebars && tag_complete[0] === '{' && tag_check === 'else') {
358
+				if (!peek) {
359
+					this.indent_to_tag('if');
360
+					this.tag_type = 'HANDLEBARS_ELSE';
361
+					this.indent_content = true;
362
+					this.traverse_whitespace();
363
+				}
364
+			} else if (tag_check === 'script') { //for later script handling
365
+				if (!peek) {
366
+					this.record_tag(tag_check);
367
+					this.tag_type = 'SCRIPT';
368
+				}
369
+			} else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
370
+				if (!peek) {
371
+					this.record_tag(tag_check);
372
+					this.tag_type = 'STYLE';
373
+				}
374
+			} else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
375
+				comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
376
+				content.push(comment);
377
+				// Preserve collapsed whitespace either before or after this tag.
378
+				if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)) {
379
+					content.splice(0, 0, this.input.charAt(tag_start - 1));
380
+				}
381
+				tag_end = this.pos - 1;
382
+				if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)) {
383
+					content.push(this.input.charAt(tag_end + 1));
384
+				}
385
+				this.tag_type = 'SINGLE';
386
+			} else if (tag_check.charAt(0) === '!') { //peek for <! comment
387
+				// for comments content is already correct.
388
+				if (!peek) {
389
+					this.tag_type = 'SINGLE';
390
+					this.traverse_whitespace();
391
+				}
392
+			} else if (!peek) {
393
+				if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
394
+					this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
395
+					this.tag_type = 'END';
396
+					this.traverse_whitespace();
397
+				} else { //otherwise it's a start-tag
398
+					this.record_tag(tag_check); //push it on the tag stack
399
+					if (tag_check.toLowerCase() !== 'html') {
400
+						this.indent_content = true;
401
+					}
402
+					this.tag_type = 'START';
403
+
404
+					// Allow preserving of newlines after a start tag
405
+					this.traverse_whitespace();
406
+				}
407
+				if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
408
+					this.print_newline(false, this.output);
409
+					if (this.output.length && this.output[this.output.length - 2] !== '\n') {
410
+						this.print_newline(true, this.output);
411
+					}
412
+				}
413
+			}
414
+
415
+			if (peek) {
416
+				this.pos = orig_pos;
417
+				this.line_char_count = orig_line_char_count;
418
+			}
419
+
420
+			return content.join(''); //returns fully formatted tag
421
+		};
422
+
423
+		this.get_comment = function(start_pos) { //function to return comment content in its entirety
424
+			// this is will have very poor perf, but will work for now.
425
+			var comment = '',
426
+				delimiter = '>',
427
+				matched = false;
428
+
429
+			this.pos = start_pos;
430
+			input_char = this.input.charAt(this.pos);
431
+			this.pos++;
432
+
433
+			while (this.pos <= this.input.length) {
434
+				comment += input_char;
435
+
436
+				// only need to check for the delimiter if the last chars match
437
+				if (comment[comment.length - 1] === delimiter[delimiter.length - 1] &&
438
+					comment.indexOf(delimiter) !== -1) {
439
+					break;
440
+				}
441
+
442
+				// only need to search for custom delimiter for the first few characters
443
+				if (!matched && comment.length < 10) {
444
+					if (comment.indexOf('<![if') === 0) { //peek for <![if conditional comment
445
+						delimiter = '<![endif]>';
446
+						matched = true;
447
+					} else if (comment.indexOf('<![cdata[') === 0) { //if it's a <[cdata[ comment...
448
+						delimiter = ']]>';
449
+						matched = true;
450
+					} else if (comment.indexOf('<![') === 0) { // some other ![ comment? ...
451
+						delimiter = ']>';
452
+						matched = true;
453
+					} else if (comment.indexOf('<!--') === 0) { // <!-- comment ...
454
+						delimiter = '-->';
455
+						matched = true;
456
+					}
457
+				}
458
+
459
+				input_char = this.input.charAt(this.pos);
460
+				this.pos++;
461
+			}
462
+
463
+			return comment;
464
+		};
465
+
466
+		this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety
467
+
468
+			if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
469
+				return '';
470
+			}
471
+			var input_char = '';
472
+			var content = '';
473
+			var min_index = 0;
474
+			var space = true;
475
+			do {
476
+
477
+				if (this.pos >= this.input.length) {
478
+					return content;
479
+				}
480
+
481
+				input_char = this.input.charAt(this.pos);
482
+				this.pos++;
483
+
484
+				if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
485
+					if (!space) {
486
+						this.line_char_count--;
487
+						continue;
488
+					}
489
+					if (input_char === '\n' || input_char === '\r') {
490
+						content += '\n';
491
+						/*  Don't change tab indention for unformatted blocks.  If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
492
+			for (var i=0; i<this.indent_level; i++) {
493
+			  content += this.indent_string;
494
+			}
495
+			space = false; //...and make sure other indentation is erased
496
+			*/
497
+						this.line_char_count = 0;
498
+						continue;
499
+					}
500
+				}
501
+				content += input_char;
502
+				this.line_char_count++;
503
+				space = true;
504
+
505
+				if (indent_handlebars && input_char === '{' && content.length && content[content.length - 2] === '{') {
506
+					// Handlebars expressions in strings should also be unformatted.
507
+					content += this.get_unformatted('}}');
508
+					// These expressions are opaque.  Ignore delimiters found in them.
509
+					min_index = content.length;
510
+				}
511
+			} while (content.toLowerCase().indexOf(delimiter, min_index) === -1);
512
+			return content;
513
+		};
514
+
515
+		this.get_token = function() { //initial handler for token-retrieval
516
+			var token;
517
+
518
+			if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
519
+				var type = this.last_token.substr(7);
520
+				token = this.get_contents_to(type);
521
+				if (typeof token !== 'string') {
522
+					return token;
523
+				}
524
+				return [token, 'TK_' + type];
525
+			}
526
+			if (this.current_mode === 'CONTENT') {
527
+				token = this.get_content();
528
+				if (typeof token !== 'string') {
529
+					return token;
530
+				} else {
531
+					return [token, 'TK_CONTENT'];
532
+				}
533
+			}
534
+
535
+			if (this.current_mode === 'TAG') {
536
+				token = this.get_tag();
537
+				if (typeof token !== 'string') {
538
+					return token;
539
+				} else {
540
+					var tag_name_type = 'TK_TAG_' + this.tag_type;
541
+					return [token, tag_name_type];
542
+				}
543
+			}
544
+		};
545
+
546
+		this.get_full_indent = function(level) {
547
+			level = this.indent_level + level || 0;
548
+			if (level < 1) {
549
+				return '';
550
+			}
551
+
552
+			return Array(level + 1).join(this.indent_string);
553
+		};
554
+
555
+		this.is_unformatted = function(tag_check, unformatted) {
556
+			//is this an HTML5 block-level link?
557
+			if (!this.Utils.in_array(tag_check, unformatted)) {
558
+				return false;
559
+			}
560
+
561
+			if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)) {
562
+				return true;
563
+			}
564
+
565
+			//at this point we have an  tag; is its first child something we want to remain
566
+			//unformatted?
567
+			var next_tag = this.get_tag(true /* peek. */ );
568
+
569
+			// test next_tag to see if it is just html tag (no external content)
570
+			var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
571
+
572
+			// if next_tag comes back but is not an isolated tag, then
573
+			// let's treat the 'a' tag as having content
574
+			// and respect the unformatted option
575
+			if (!tag || this.Utils.in_array(tag, unformatted)) {
576
+				return true;
577
+			} else {
578
+				return false;
579
+			}
580
+		};
581
+
582
+		this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions
583
+
584
+			this.input = js_source || ''; //gets the input for the Parser
585
+			this.output = [];
586
+			this.indent_character = indent_character;
587
+			this.indent_string = '';
588
+			this.indent_size = indent_size;
589
+			this.brace_style = brace_style;
590
+			this.indent_level = 0;
591
+			this.wrap_line_length = wrap_line_length;
592
+			this.line_char_count = 0; //count to see if wrap_line_length was exceeded
593
+
594
+			for (var i = 0; i < this.indent_size; i++) {
595
+				this.indent_string += this.indent_character;
596
+			}
597
+
598
+			this.print_newline = function(force, arr) {
599
+				this.line_char_count = 0;
600
+				if (!arr || !arr.length) {
601
+					return;
602
+				}
603
+				if (force || (arr[arr.length - 1] !== '\n')) { //we might want the extra line
604
+					arr.push('\n');
605
+				}
606
+			};
607
+
608
+			this.print_indentation = function(arr) {
609
+				for (var i = 0; i < this.indent_level; i++) {
610
+					arr.push(this.indent_string);
611
+					this.line_char_count += this.indent_string.length;
612
+				}
613
+			};
614
+
615
+			this.print_token = function(text) {
616
+				if (text || text !== '') {
617
+					if (this.output.length && this.output[this.output.length - 1] === '\n') {
618
+						this.print_indentation(this.output);
619
+						text = ltrim(text);
620
+					}
621
+				}
622
+				this.print_token_raw(text);
623
+			};
624
+
625
+			this.print_token_raw = function(text) {
626
+				if (text && text !== '') {
627
+					if (text.length > 1 && text[text.length - 1] === '\n') {
628
+						// unformatted tags can grab newlines as their last character
629
+						this.output.push(text.slice(0, -1));
630
+						this.print_newline(false, this.output);
631
+					} else {
632
+						this.output.push(text);
633
+					}
634
+				}
635
+
636
+				for (var n = 0; n < this.newlines; n++) {
637
+					this.print_newline(n > 0, this.output);
638
+				}
639
+				this.newlines = 0;
640
+			};
641
+
642
+			this.indent = function() {
643
+				this.indent_level++;
644
+			};
645
+
646
+			this.unindent = function() {
647
+				if (this.indent_level > 0) {
648
+					this.indent_level--;
649
+				}
650
+			};
651
+		};
652
+		return this;
653
+	}
654
+
655
+	/*_____________________--------------------_____________________*/
656
+
657
+	multi_parser = new Parser(); //wrapping functions Parser
658
+	multi_parser.printer(html_source, indent_character, indent_size, wrap_line_length, brace_style); //initialize starting values
659
+
660
+	while (true) {
661
+		var t = multi_parser.get_token();
662
+		multi_parser.token_text = t[0];
663
+		multi_parser.token_type = t[1];
664
+
665
+		if (multi_parser.token_type === 'TK_EOF') {
666
+			break;
667
+		}
668
+
669
+		switch (multi_parser.token_type) {
670
+			case 'TK_TAG_START':
671
+				multi_parser.print_newline(false, multi_parser.output);
672
+				multi_parser.print_token(multi_parser.token_text);
673
+				if (multi_parser.indent_content) {
674
+					multi_parser.indent();
675
+					multi_parser.indent_content = false;
676
+				}
677
+				multi_parser.current_mode = 'CONTENT';
678
+				break;
679
+			case 'TK_TAG_STYLE':
680
+			case 'TK_TAG_SCRIPT':
681
+				multi_parser.print_newline(false, multi_parser.output);
682
+				multi_parser.print_token(multi_parser.token_text);
683
+				multi_parser.current_mode = 'CONTENT';
684
+				break;
685
+			case 'TK_TAG_END':
686
+				//Print new line only if the tag has no content and has child
687
+				if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
688
+					var tag_name = multi_parser.token_text.match(/\w+/)[0];
689
+					var tag_extracted_from_last_output = null;
690
+					if (multi_parser.output.length) {
691
+						tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/(?:<|{{#)\s*(\w+)/);
692
+					}
693
+					if (tag_extracted_from_last_output === null ||
694
+						tag_extracted_from_last_output[1] !== tag_name) {
695
+						multi_parser.print_newline(false, multi_parser.output);
696
+					}
697
+				}
698
+				multi_parser.print_token(multi_parser.token_text);
699
+				multi_parser.current_mode = 'CONTENT';
700
+				break;
701
+			case 'TK_TAG_SINGLE':
702
+				// Don't add a newline before elements that should remain unformatted.
703
+				var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
704
+				if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)) {
705
+					multi_parser.print_newline(false, multi_parser.output);
706
+				}
707
+				multi_parser.print_token(multi_parser.token_text);
708
+				multi_parser.current_mode = 'CONTENT';
709
+				break;
710
+			case 'TK_TAG_HANDLEBARS_ELSE':
711
+				multi_parser.print_token(multi_parser.token_text);
712
+				if (multi_parser.indent_content) {
713
+					multi_parser.indent();
714
+					multi_parser.indent_content = false;
715
+				}
716
+				multi_parser.current_mode = 'CONTENT';
717
+				break;
718
+			case 'TK_CONTENT':
719
+				multi_parser.print_token(multi_parser.token_text);
720
+				multi_parser.current_mode = 'TAG';
721
+				break;
722
+			case 'TK_STYLE':
723
+			case 'TK_SCRIPT':
724
+				if (multi_parser.token_text !== '') {
725
+					multi_parser.print_newline(false, multi_parser.output);
726
+					var text = multi_parser.token_text,
727
+						_beautifier,
728
+						script_indent_level = 1;
729
+					if (multi_parser.token_type === 'TK_SCRIPT') {
730
+						_beautifier = typeof js_beautify === 'function' && js_beautify;
731
+					} else if (multi_parser.token_type === 'TK_STYLE') {
732
+						_beautifier = typeof css_beautify === 'function' && css_beautify;
733
+					}
734
+
735
+					if (options.indent_scripts === "keep") {
736
+						script_indent_level = 0;
737
+					} else if (options.indent_scripts === "separate") {
738
+						script_indent_level = -multi_parser.indent_level;
739
+					}
740
+
741
+					var indentation = multi_parser.get_full_indent(script_indent_level);
742
+					if (_beautifier) {
743
+						// call the Beautifier if avaliable
744
+						text = _beautifier(text.replace(/^\s*/, indentation), options);
745
+					} else {
746
+						// simply indent the string otherwise
747
+						var white = text.match(/^\s*/)[0];
748
+						var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
749
+						var reindent = multi_parser.get_full_indent(script_indent_level - _level);
750
+						text = text.replace(/^\s*/, indentation)
751
+							.replace(/\r\n|\r|\n/g, '\n' + reindent)
752
+							.replace(/\s+$/, '');
753
+					}
754
+					if (text) {
755
+						multi_parser.print_token_raw(indentation + trim(text));
756
+						multi_parser.print_newline(false, multi_parser.output);
757
+					}
758
+				}
759
+				multi_parser.current_mode = 'TAG';
760
+				break;
761
+		}
762
+		multi_parser.last_token = multi_parser.token_type;
763
+		multi_parser.last_text = multi_parser.token_text;
764
+	}
765
+	return multi_parser.output.join('');
766
+}

+ 689
- 0
src/ZSSRichTextEditor/ZSSRichTextEditor.js 查看文件

@@ -0,0 +1,689 @@
1
+/*!
2
+ *
3
+ * ZSSRichTextEditor v0.5.2
4
+ * http://www.zedsaid.com
5
+ *
6
+ * Copyright 2014 Zed Said Studio LLC
7
+ *
8
+ */
9
+
10
+var zss_editor = {};
11
+
12
+// If we are using iOS or desktop
13
+zss_editor.isUsingiOS = true;
14
+
15
+// If the user is draging
16
+zss_editor.isDragging = false;
17
+
18
+// The current selection
19
+zss_editor.currentSelection;
20
+
21
+// The current editing image
22
+zss_editor.currentEditingImage;
23
+
24
+// The current editing link
25
+zss_editor.currentEditingLink;
26
+
27
+// The objects that are enabled
28
+zss_editor.enabledItems = {};
29
+
30
+// Height of content window, will be set by viewController
31
+zss_editor.contentHeight = 244;
32
+
33
+// Sets to true when extra footer gap shows and requires to hide
34
+zss_editor.updateScrollOffset = false;
35
+
36
+/**
37
+ * The initializer function that must be called onLoad
38
+ */
39
+zss_editor.init = function() {
40
+
41
+    $('#zss_editor_content').on('touchend', function(e) {
42
+                                zss_editor.enabledEditingItems(e);
43
+                                var clicked = $(e.target);
44
+                                if (!clicked.hasClass('zs_active')) {
45
+                                $('img').removeClass('zs_active');
46
+                                }
47
+                                });
48
+    
49
+    $(document).on('selectionchange',function(e){
50
+                   zss_editor.calculateEditorHeightWithCaretPosition();
51
+                   zss_editor.setScrollPosition();
52
+                   zss_editor.enabledEditingItems(e);
53
+                   });
54
+    
55
+    $(window).on('scroll', function(e) {
56
+                 zss_editor.updateOffset();
57
+                 });
58
+    
59
+    // Make sure that when we tap anywhere in the document we focus on the editor
60
+    $(window).on('touchmove', function(e) {
61
+                 zss_editor.isDragging = true;
62
+                 zss_editor.updateScrollOffset = true;
63
+                 zss_editor.setScrollPosition();
64
+                 zss_editor.enabledEditingItems(e);
65
+                 });
66
+    $(window).on('touchstart', function(e) {
67
+                 zss_editor.isDragging = false;
68
+                 });
69
+    $(window).on('touchend', function(e) {
70
+                 if (!zss_editor.isDragging && (e.target.id == "zss_editor_footer"||e.target.nodeName.toLowerCase() == "html")) {
71
+                 zss_editor.focusEditor();
72
+                 }
73
+                 });
74
+    
75
+}//end
76
+
77
+zss_editor.updateOffset = function() {
78
+    
79
+    if (!zss_editor.updateScrollOffset)
80
+        return;
81
+    
82
+    var offsetY = window.document.body.scrollTop;
83
+    
84
+    var footer = $('#zss_editor_footer');
85
+    
86
+    var maxOffsetY = footer.offset().top - zss_editor.contentHeight;
87
+    
88
+    if (maxOffsetY < 0)
89
+        maxOffsetY = 0;
90
+    
91
+    if (offsetY > maxOffsetY)
92
+    {
93
+        window.scrollTo(0, maxOffsetY);
94
+    }
95
+    
96
+    zss_editor.setScrollPosition();
97
+}
98
+
99
+// This will show up in the XCode console as we are able to push this into an NSLog.
100
+zss_editor.debug = function(msg) {
101
+    WebViewBridge.send('debug://'+msg);
102
+}
103
+
104
+
105
+zss_editor.setScrollPosition = function() {
106
+    var position = window.pageYOffset;
107
+    WebViewBridge.send('scroll://'+position);
108
+}
109
+
110
+
111
+zss_editor.setPlaceholder = function(placeholder) {
112
+    
113
+    var editor = $('#zss_editor_content');
114
+    
115
+    //set placeHolder
116
+	editor.attr("placeholder",placeholder);
117
+	
118
+    //set focus			 
119
+	editor.focusout(function(){
120
+        var element = $(this);        
121
+        if (!element.text().trim().length) {
122
+            element.empty();
123
+        }
124
+    });
125
+	
126
+	
127
+    
128
+}
129
+
130
+zss_editor.setFooterHeight = function(footerHeight) {
131
+    var footer = $('#zss_editor_footer');
132
+    footer.height(footerHeight + 'px');
133
+}
134
+
135
+zss_editor.getCaretYPosition = function() {
136
+    var sel = window.getSelection();
137
+    // Next line is comented to prevent deselecting selection. It looks like work but if there are any issues will appear then uconmment it as well as code above.
138
+    //sel.collapseToStart();
139
+    var range = sel.getRangeAt(0);
140
+    var span = document.createElement('span');// something happening here preventing selection of elements
141
+    range.collapse(false);
142
+    range.insertNode(span);
143
+    var topPosition = span.offsetTop;
144
+    span.parentNode.removeChild(span);
145
+    return topPosition;
146
+}
147
+
148
+zss_editor.calculateEditorHeightWithCaretPosition = function() {
149
+    
150
+    var padding = 50;
151
+    var c = zss_editor.getCaretYPosition();
152
+    var e = document.getElementById('zss_editor_content');
153
+    
154
+    var editor = $('#zss_editor_content');
155
+    
156
+    var offsetY = window.document.body.scrollTop;
157
+    var height = zss_editor.contentHeight;
158
+    
159
+    var newPos = window.pageYOffset;
160
+    
161
+    if (c < offsetY) {
162
+        newPos = c;
163
+    } else if (c > (offsetY + height - padding)) {
164
+        var newPos = c - height + padding - 18;
165
+    }
166
+    
167
+    window.scrollTo(0, newPos);
168
+}
169
+
170
+zss_editor.backuprange = function(){
171
+    var selection = window.getSelection();
172
+    var range = selection.getRangeAt(0);
173
+    zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
174
+}
175
+
176
+zss_editor.restorerange = function(){
177
+    var selection = window.getSelection();
178
+    selection.removeAllRanges();
179
+    var range = document.createRange();
180
+    range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
181
+    range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
182
+    selection.addRange(range);
183
+}
184
+
185
+zss_editor.getSelectedNode = function() {
186
+    var node,selection;
187
+    if (window.getSelection) {
188
+        selection = getSelection();
189
+        node = selection.anchorNode;
190
+    }
191
+    if (!node && document.selection) {
192
+        selection = document.selection
193
+        var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
194
+        node = range.commonAncestorContainer ? range.commonAncestorContainer :
195
+        range.parentElement ? range.parentElement() : range.item(0);
196
+    }
197
+    if (node) {
198
+        return (node.nodeName == "#text" ? node.parentNode : node);
199
+    }
200
+};
201
+
202
+zss_editor.setBold = function() {
203
+    document.execCommand('bold', false, null);
204
+    zss_editor.enabledEditingItems();
205
+}
206
+
207
+zss_editor.setItalic = function() {
208
+    document.execCommand('italic', false, null);
209
+    zss_editor.enabledEditingItems();
210
+}
211
+
212
+zss_editor.setSubscript = function() {
213
+    document.execCommand('subscript', false, null);
214
+    zss_editor.enabledEditingItems();
215
+}
216
+
217
+zss_editor.setSuperscript = function() {
218
+    document.execCommand('superscript', false, null);
219
+    zss_editor.enabledEditingItems();
220
+}
221
+
222
+zss_editor.setStrikeThrough = function() {
223
+    document.execCommand('strikeThrough', false, null);
224
+    zss_editor.enabledEditingItems();
225
+}
226
+
227
+zss_editor.setUnderline = function() {
228
+    document.execCommand('underline', false, null);
229
+    zss_editor.enabledEditingItems();
230
+}
231
+
232
+zss_editor.setBlockquote = function() {
233
+    document.execCommand('formatBlock', false, '<blockquote>');
234
+    zss_editor.enabledEditingItems();
235
+}
236
+
237
+zss_editor.removeFormating = function() {
238
+    document.execCommand('removeFormat', false, null);
239
+    zss_editor.enabledEditingItems();
240
+}
241
+
242
+zss_editor.setHorizontalRule = function() {
243
+    document.execCommand('insertHorizontalRule', false, null);
244
+    zss_editor.enabledEditingItems();
245
+}
246
+
247
+zss_editor.setHeading = function(heading) {
248
+    var current_selection = $(zss_editor.getSelectedNode());
249
+    var t = current_selection.prop("tagName").toLowerCase();
250
+    var is_heading = (t == 'h1' || t == 'h2' || t == 'h3' || t == 'h4' || t == 'h5' || t == 'h6');
251
+    if (is_heading && heading == t) {
252
+        var c = current_selection.html();
253
+        current_selection.replaceWith(c);
254
+    } else {
255
+        document.execCommand('formatBlock', false, '<'+heading+'>');
256
+    }
257
+    
258
+    zss_editor.enabledEditingItems();
259
+}
260
+
261
+zss_editor.setParagraph = function() {
262
+    var current_selection = $(zss_editor.getSelectedNode());
263
+    var t = current_selection.prop("tagName").toLowerCase();
264
+    var is_paragraph = (t == 'p');
265
+    if (is_paragraph) {
266
+        var c = current_selection.html();
267
+        current_selection.replaceWith(c);
268
+    } else {
269
+        document.execCommand('formatBlock', false, '<p>');
270
+    }
271
+    
272
+    zss_editor.enabledEditingItems();
273
+}
274
+
275
+// Need way to remove formatBlock
276
+console.log('WARNING: We need a way to remove formatBlock items');
277
+
278
+zss_editor.undo = function() {
279
+    document.execCommand('undo', false, null);
280
+    zss_editor.enabledEditingItems();
281
+}
282
+
283
+zss_editor.redo = function() {
284
+    document.execCommand('redo', false, null);
285
+    zss_editor.enabledEditingItems();
286
+}
287
+
288
+zss_editor.setOrderedList = function() {
289
+    document.execCommand('insertOrderedList', false, null);
290
+    zss_editor.enabledEditingItems();
291
+}
292
+
293
+zss_editor.setUnorderedList = function() {
294
+    document.execCommand('insertUnorderedList', false, null);
295
+    zss_editor.enabledEditingItems();
296
+}
297
+
298
+zss_editor.setJustifyCenter = function() {
299
+    document.execCommand('justifyCenter', false, null);
300
+    zss_editor.enabledEditingItems();
301
+}
302
+
303
+zss_editor.setJustifyFull = function() {
304
+    document.execCommand('justifyFull', false, null);
305
+    zss_editor.enabledEditingItems();
306
+}
307
+
308
+zss_editor.setJustifyLeft = function() {
309
+    document.execCommand('justifyLeft', false, null);
310
+    zss_editor.enabledEditingItems();
311
+}
312
+
313
+zss_editor.setJustifyRight = function() {
314
+    document.execCommand('justifyRight', false, null);
315
+    zss_editor.enabledEditingItems();
316
+}
317
+
318
+zss_editor.setIndent = function() {
319
+    document.execCommand('indent', false, null);
320
+    zss_editor.enabledEditingItems();
321
+}
322
+
323
+zss_editor.setOutdent = function() {
324
+    document.execCommand('outdent', false, null);
325
+    zss_editor.enabledEditingItems();
326
+}
327
+
328
+zss_editor.setFontFamily = function(fontFamily) {
329
+
330
+	zss_editor.restorerange();
331
+	document.execCommand("styleWithCSS", null, true);
332
+	document.execCommand("fontName", false, fontFamily);
333
+	document.execCommand("styleWithCSS", null, false);
334
+	zss_editor.enabledEditingItems();
335
+		
336
+}
337
+
338
+zss_editor.setTextColor = function(color) {
339
+		
340
+    zss_editor.restorerange();
341
+    document.execCommand("styleWithCSS", null, true);
342
+    document.execCommand('foreColor', false, color);
343
+    document.execCommand("styleWithCSS", null, false);
344
+    zss_editor.enabledEditingItems();
345
+    // document.execCommand("removeFormat", false, "foreColor"); // Removes just foreColor
346
+	
347
+}
348
+
349
+zss_editor.setBackgroundColor = function(color) {
350
+    zss_editor.restorerange();
351
+    document.execCommand("styleWithCSS", null, true);
352
+    document.execCommand('hiliteColor', false, color);
353
+    document.execCommand("styleWithCSS", null, false);
354
+    zss_editor.enabledEditingItems();
355
+}
356
+
357
+// Needs addClass method
358
+
359
+zss_editor.insertLink = function(url, title) {
360
+    
361
+    zss_editor.restorerange();
362
+    var sel = document.getSelection();
363
+    console.log(sel);
364
+    if (sel.toString().length != 0) {
365
+        if (sel.rangeCount) {
366
+            
367
+            var el = document.createElement("a");
368
+            el.setAttribute("href", url);
369
+            el.setAttribute("title", title);
370
+            
371
+            var range = sel.getRangeAt(0).cloneRange();
372
+            range.surroundContents(el);
373
+            sel.removeAllRanges();
374
+            sel.addRange(range);
375
+        }
376
+    }
377
+    else
378
+    {
379
+        document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
380
+    }
381
+    
382
+    zss_editor.enabledEditingItems();
383
+}
384
+
385
+zss_editor.updateLink = function(url, title) {
386
+    
387
+    zss_editor.restorerange();
388
+    
389
+    if (zss_editor.currentEditingLink) {
390
+        var c = zss_editor.currentEditingLink;
391
+        c.attr('href', url);
392
+        c.attr('title', title);
393
+    }
394
+    zss_editor.enabledEditingItems();
395
+    
396
+}//end
397
+
398
+zss_editor.updateImage = function(url, alt) {
399
+    
400
+    zss_editor.restorerange();
401
+    
402
+    if (zss_editor.currentEditingImage) {
403
+        var c = zss_editor.currentEditingImage;
404
+        c.attr('src', url);
405
+        c.attr('alt', alt);
406
+    }
407
+    zss_editor.enabledEditingItems();
408
+    
409
+}//end
410
+
411
+zss_editor.updateImageBase64String = function(imageBase64String, alt) {
412
+    
413
+    zss_editor.restorerange();
414
+    
415
+    if (zss_editor.currentEditingImage) {
416
+        var c = zss_editor.currentEditingImage;
417
+        var src = 'data:image/jpeg;base64,' + imageBase64String;
418
+        c.attr('src', src);
419
+        c.attr('alt', alt);
420
+    }
421
+    zss_editor.enabledEditingItems();
422
+    
423
+}//end
424
+
425
+
426
+zss_editor.unlink = function() {
427
+    
428
+    if (zss_editor.currentEditingLink) {
429
+        var c = zss_editor.currentEditingLink;
430
+        c.contents().unwrap();
431
+    }
432
+    zss_editor.enabledEditingItems();
433
+}
434
+
435
+zss_editor.quickLink = function() {
436
+    
437
+    var sel = document.getSelection();
438
+    var link_url = "";
439
+    var test = new String(sel);
440
+    var mailregexp = new RegExp("^(.+)(\@)(.+)$", "gi");
441
+    if (test.search(mailregexp) == -1) {
442
+        checkhttplink = new RegExp("^http\:\/\/", "gi");
443
+        if (test.search(checkhttplink) == -1) {
444
+            checkanchorlink = new RegExp("^\#", "gi");
445
+            if (test.search(checkanchorlink) == -1) {
446
+                link_url = "http://" + sel;
447
+            } else {
448
+                link_url = sel;
449
+            }
450
+        } else {
451
+            link_url = sel;
452
+        }
453
+    } else {
454
+        checkmaillink = new RegExp("^mailto\:", "gi");
455
+        if (test.search(checkmaillink) == -1) {
456
+            link_url = "mailto:" + sel;
457
+        } else {
458
+            link_url = sel;
459
+        }
460
+    }
461
+    
462
+    var html_code = '<a href="' + link_url + '">' + sel + '</a>';
463
+    zss_editor.insertHTML(html_code);
464
+    
465
+}
466
+
467
+zss_editor.prepareInsert = function() {
468
+    zss_editor.backuprange();
469
+}
470
+
471
+zss_editor.insertImage = function(url, alt) {
472
+    zss_editor.restorerange();
473
+    var html = '<img src="'+url+'" alt="'+alt+'" />';
474
+    zss_editor.insertHTML(html);
475
+    zss_editor.enabledEditingItems();
476
+}
477
+
478
+zss_editor.insertImageBase64String = function(imageBase64String, alt) {
479
+    zss_editor.restorerange();
480
+    var html = '<img src="data:image/jpeg;base64,'+imageBase64String+'" alt="'+alt+'" />';
481
+    zss_editor.insertHTML(html);
482
+    zss_editor.enabledEditingItems();
483
+}
484
+
485
+zss_editor.setHTML = function(html) {
486
+    var editor = $('#zss_editor_content');
487
+    editor.html(html);
488
+}
489
+
490
+zss_editor.insertHTML = function(html) {
491
+    document.execCommand('insertHTML', false, html);
492
+    zss_editor.enabledEditingItems();
493
+}
494
+
495
+zss_editor.getHTML = function() {
496
+    
497
+    // Images
498
+    var img = $('img');
499
+    if (img.length != 0) {
500
+        $('img').removeClass('zs_active');
501
+        $('img').each(function(index, e) {
502
+                      var image = $(this);
503
+                      var zs_class = image.attr('class');
504
+                      if (typeof(zs_class) != "undefined") {
505
+                      if (zs_class == '') {
506
+                      image.removeAttr('class');
507
+                      }
508
+                      }
509
+                      });
510
+    }
511
+    
512
+    // Blockquote
513
+    var bq = $('blockquote');
514
+    if (bq.length != 0) {
515
+        bq.each(function() {
516
+                var b = $(this);
517
+                if (b.css('border').indexOf('none') != -1) {
518
+                b.css({'border': ''});
519
+                }
520
+                if (b.css('padding').indexOf('0px') != -1) {
521
+                b.css({'padding': ''});
522
+                }
523
+                });
524
+    }
525
+    
526
+    // Get the contents
527
+    var h = document.getElementById("zss_editor_content").innerHTML;
528
+    
529
+    return h;
530
+}
531
+
532
+zss_editor.getText = function() {
533
+    return $('#zss_editor_content').text();
534
+}
535
+
536
+zss_editor.isCommandEnabled = function(commandName) {
537
+    return document.queryCommandState(commandName);
538
+}
539
+
540
+zss_editor.enabledEditingItems = function(e) {
541
+    
542
+    console.log('enabledEditingItems');
543
+    var items = [];
544
+    if (zss_editor.isCommandEnabled('bold')) {
545
+        items.push('bold');
546
+    }
547
+    if (zss_editor.isCommandEnabled('italic')) {
548
+        items.push('italic');
549
+    }
550
+    if (zss_editor.isCommandEnabled('subscript')) {
551
+        items.push('subscript');
552
+    }
553
+    if (zss_editor.isCommandEnabled('superscript')) {
554
+        items.push('superscript');
555
+    }
556
+    if (zss_editor.isCommandEnabled('strikeThrough')) {
557
+        items.push('strikeThrough');
558
+    }
559
+    if (zss_editor.isCommandEnabled('underline')) {
560
+        items.push('underline');
561
+    }
562
+    if (zss_editor.isCommandEnabled('insertOrderedList')) {
563
+        items.push('orderedList');
564
+    }
565
+    if (zss_editor.isCommandEnabled('insertUnorderedList')) {
566
+        items.push('unorderedList');
567
+    }
568
+    if (zss_editor.isCommandEnabled('justifyCenter')) {
569
+        items.push('justifyCenter');
570
+    }
571
+    if (zss_editor.isCommandEnabled('justifyFull')) {
572
+        items.push('justifyFull');
573
+    }
574
+    if (zss_editor.isCommandEnabled('justifyLeft')) {
575
+        items.push('justifyLeft');
576
+    }
577
+    if (zss_editor.isCommandEnabled('justifyRight')) {
578
+        items.push('justifyRight');
579
+    }
580
+    if (zss_editor.isCommandEnabled('insertHorizontalRule')) {
581
+        items.push('horizontalRule');
582
+    }
583
+    var formatBlock = document.queryCommandValue('formatBlock');
584
+    if (formatBlock.length > 0) {
585
+        items.push(formatBlock);
586
+    }
587
+    // Images
588
+    $('img').bind('touchstart', function(e) {
589
+                  $('img').removeClass('zs_active');
590
+                  $(this).addClass('zs_active');
591
+                  });
592
+    
593
+    // Use jQuery to figure out those that are not supported
594
+    if (typeof(e) != "undefined") {
595
+        
596
+        // The target element
597
+        var s = zss_editor.getSelectedNode();
598
+        var t = $(s);
599
+        var nodeName = e.target.nodeName.toLowerCase();
600
+        
601
+        // Background Color
602
+        var bgColor = t.css('backgroundColor');
603
+        if (bgColor.length != 0 && bgColor != 'rgba(0, 0, 0, 0)' && bgColor != 'rgb(0, 0, 0)' && bgColor != 'transparent') {
604
+            items.push('backgroundColor');
605
+        }
606
+        // Text Color
607
+        var textColor = t.css('color');
608
+        if (textColor.length != 0 && textColor != 'rgba(0, 0, 0, 0)' && textColor != 'rgb(0, 0, 0)' && textColor != 'transparent') {
609
+            items.push('textColor');
610
+        }
611
+		
612
+		//Fonts
613
+		var font = t.css('font-family');
614
+		if (font.length != 0 && font != 'Arial, Helvetica, sans-serif') {
615
+			items.push('fonts');	
616
+		}
617
+		
618
+        // Link
619
+        if (nodeName == 'a') {
620
+            zss_editor.currentEditingLink = t;
621
+            var title = t.attr('title');
622
+            items.push('link:'+t.attr('href'));
623
+            if (t.attr('title') !== undefined) {
624
+                items.push('link-title:'+t.attr('title'));
625
+            }
626
+            
627
+        } else {
628
+            zss_editor.currentEditingLink = null;
629
+        }
630
+        // Blockquote
631
+        if (nodeName == 'blockquote') {
632
+            items.push('indent');
633
+        }
634
+        // Image
635
+        if (nodeName == 'img') {
636
+            zss_editor.currentEditingImage = t;
637
+            items.push('image:'+t.attr('src'));
638
+            if (t.attr('alt') !== undefined) {
639
+                items.push('image-alt:'+t.attr('alt'));
640
+            }
641
+            
642
+        } else {
643
+            zss_editor.currentEditingImage = null;
644
+        }
645
+        
646
+    }
647
+    
648
+    if (items.length > 0) {
649
+        WebViewBridge.send('callback://0/"+items.join(',')');
650
+    } else {
651
+        WebViewBridge.send('zss-callback/');
652
+    }
653
+}
654
+
655
+zss_editor.focusEditor = function() {
656
+    
657
+    // the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
658
+    // and ensures we move the cursor to the end of the editor
659
+    var editor = $('#zss_editor_content');
660
+    var range = document.createRange();
661
+    range.selectNodeContents(editor.get(0));
662
+    range.collapse(false);
663
+    var selection = window.getSelection();
664
+    selection.removeAllRanges();
665
+    selection.addRange(range);
666
+    editor.focus();
667
+}
668
+
669
+zss_editor.blurEditor = function() {
670
+    $('#zss_editor_content').blur();
671
+}
672
+
673
+zss_editor.setCustomCSS = function(customCSS) {
674
+    
675
+    document.getElementsByTagName('style')[0].innerHTML=customCSS;
676
+    
677
+    //set focus
678
+    /*editor.focusout(function(){
679
+                    var element = $(this);
680
+                    if (!element.text().trim().length) {
681
+                    element.empty();
682
+                    }
683
+                    });*/
684
+    
685
+    
686
+    
687
+}
688
+
689
+//end

+ 4
- 0
src/ZSSRichTextEditor/jQuery.js
文件差異過大導致無法顯示
查看文件


+ 51
- 0
src/ZSSRichTextEditor/style.css 查看文件

@@ -0,0 +1,51 @@
1
+/* Default ZSSRichTextEditor Styling */
2
+* {
3
+    outline: 0px solid transparent;
4
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
5
+    -webkit-touch-callout: none;
6
+}
7
+
8
+html, body {
9
+    padding: 0;
10
+    margin: 0;
11
+    font-family: Arial, Helvetica, sans-serif;
12
+}
13
+
14
+body {
15
+    padding: 10px;
16
+    overflow-y: scroll;
17
+    -webkit-overflow-scrolling: touch;
18
+    height: 100%;
19
+}
20
+
21
+img.zs_active {
22
+    border: 2px dashed #000;
23
+}
24
+
25
+img {
26
+    width: 98%;
27
+    margin-left:auto;
28
+    margin-right:auto;
29
+}
30
+
31
+audio {
32
+    padding: 20px 0;
33
+}
34
+
35
+div.zs_editor_content {
36
+    font-family: Arial, Helvetica, sans-serif;
37
+    color: #000;
38
+    width: 100%;
39
+    height: 100%;
40
+    -webkit-overflow-scrolling: touch;
41
+    overflow:auto;
42
+}
43
+
44
+[placeholder]:empty:before {
45
+    content: attr(placeholder);
46
+    color: #555;
47
+}
48
+
49
+[placeholder]:empty:focus:before {
50
+    content: "";
51
+}

+ 4
- 0
src/const.js 查看文件

@@ -0,0 +1,4 @@
1
+export const actions = {
2
+  setHtml: 'SET_HTML',
3
+
4
+}

+ 22
- 0
src/editor.html 查看文件

@@ -0,0 +1,22 @@
1
+<!DOCTYPE html>
2
+<html>
3
+	<head>
4
+		<title>ZSSRichTextEditor</title>
5
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6
+		<!-- jQuery Source For ZSSRichTextEditor -->
7
+		<script type="text/javascript" src="ZSSRichTextEditor/jQuery.js"></script>
8
+		<!-- JSBeautifier Source for ZSSRichTextEditor -->
9
+		<script type="text/javascript" src="ZSSRichTextEditor/JSBeautifier.js"></script>
10
+		<!-- Javascript for ZSSRichTextEditor -->
11
+        <script type="text/javascript" src="ZSSRichTextEditor/ZSSRichTextEditor.js"></script>
12
+		<!-- CSS Styles for ZSSRichTextEditor -->
13
+		<link rel="stylesheet" type="text/css" href="ZSSRichTextEditor/style.css">
14
+	</head>
15
+
16
+	<body onLoad="zss_editor.init();">
17
+		<!-- ZSSRichTextEditor Editable Content -->
18
+		<div id="zss_editor_content" class="zs_editor_content" contenteditable="true" placeholder=""></div>
19
+		<!-- Footer -->
20
+		<div id="zss_editor_footer"></div>
21
+	</body>
22
+</html>