Add support for syntax highlighting for languages other than JS

Summary:
The current website defaults to using JavaScript for any code block, regardless of language tag. This PR adds syntax highlighting support by passing the necessary language prop and by adding any missing languages to Marked.js.

Depends on #14212, #14065
Closes https://github.com/facebook/react-native/pull/14215

Differential Revision: D5149897

Pulled By: hramos

fbshipit-source-id: 95a817af2168d5743c75dd1ac030d399a68fb93c
This commit is contained in:
Hector Ramos 2017-05-30 14:30:38 -07:00 коммит произвёл Facebook Github Bot
Родитель b1ecb84c97
Коммит 0a6935618c
8 изменённых файлов: 880 добавлений и 417 удалений

Просмотреть файл

@ -240,7 +240,7 @@ React Native also requires a recent version of the [Java SE Development Kit (JDK
Open an Administrator Command Prompt (right click Command Prompt and select "Run as Administrator"), then run the following commands: Open an Administrator Command Prompt (right click Command Prompt and select "Run as Administrator"), then run the following commands:
``` ```powershell
choco install nodejs.install choco install nodejs.install
choco install python2 choco install python2
choco install jdk8 choco install jdk8
@ -272,7 +272,7 @@ Node comes with npm, which lets you install the React Native command line interf
Run the following command in a Command Prompt or shell: Run the following command in a Command Prompt or shell:
``` ```powershell
npm install -g react-native-cli npm install -g react-native-cli
``` ```
@ -430,7 +430,7 @@ Open the System pane under **System and Security** in the Control Panel, then cl
The SDK is installed, by default, at the following location: The SDK is installed, by default, at the following location:
``` ```powershell
c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk
``` ```
@ -646,7 +646,6 @@ function displayTab(type, value) {
var container = document.getElementsByTagName('block')[0].parentNode; var container = document.getElementsByTagName('block')[0].parentNode;
container.className = 'display-' + type + '-' + value + ' ' + container.className = 'display-' + type + '-' + value + ' ' +
container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), ''); container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), '');
console.log(container.className);
event && event.preventDefault(); event && event.preventDefault();
} }
</script> </script>

Просмотреть файл

@ -143,7 +143,7 @@ To ensure a smooth experience, create a new folder for your integrated React Nat
Go to the root directory for your project and create a new `package.json` file with the following contents: Go to the root directory for your project and create a new `package.json` file with the following contents:
```bash ```
{ {
"name": "MyReactNativeApp", "name": "MyReactNativeApp",
"version": "0.0.1", "version": "0.0.1",
@ -156,7 +156,7 @@ Go to the root directory for your project and create a new `package.json` file w
Next, you will install the `react` and `react-native` packages. Open a terminal or command prompt, then navigate to the root directory for your project and type the following commands: Next, you will install the `react` and `react-native` packages. Open a terminal or command prompt, then navigate to the root directory for your project and type the following commands:
```bash ```
$ npm install --save react react-native $ npm install --save react react-native
``` ```
@ -170,7 +170,7 @@ This will create a new `/node_modules` folder in your project's root directory.
We recommend installing CocoaPods using [Homebrew](http://brew.sh/). We recommend installing CocoaPods using [Homebrew](http://brew.sh/).
```bash ```
$ brew install cocoapods $ brew install cocoapods
``` ```
@ -200,7 +200,7 @@ The list of supported `subspec`s is available in [`/node_modules/react-native/Re
You can specify which `subspec`s your app will depend on in a `Podfile` file. The easiest way to create a `Podfile` is by running the CocoaPods `init` command in the `/ios` subfolder of your project: You can specify which `subspec`s your app will depend on in a `Podfile` file. The easiest way to create a `Podfile` is by running the CocoaPods `init` command in the `/ios` subfolder of your project:
```bash ```
$ pod init $ pod init
``` ```
@ -258,13 +258,13 @@ end
After you have created your `Podfile`, you are ready to install the React Native pod. After you have created your `Podfile`, you are ready to install the React Native pod.
```bash ```
$ pod install $ pod install
``` ```
You should see output such as: You should see output such as:
```bash ```
Analyzing dependencies Analyzing dependencies
Fetching podspec for `React` from `../node_modules/react-native` Fetching podspec for `React` from `../node_modules/react-native`
Downloading dependencies Downloading dependencies
@ -299,7 +299,7 @@ First, create an empty `index.ios.js` file in the root of your React Native proj
In your `index.ios.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>` In your `index.ios.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>`
```js ```javascript
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
@ -377,21 +377,21 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
First `import` the `RCTRootView` header. First `import` the `RCTRootView` header.
``` ```objectivec
#import <React/RCTRootView.h> #import <React/RCTRootView.h>
``` ```
> The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data. > The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data.
``` ```objectivec
- (IBAction)highScoreButtonPressed:(id)sender { - (IBAction)highScoreButtonPressed:(id)sender {
NSLog(@"High Score Button Pressed"); NSLog(@"High Score Button Pressed");
NSURL *jsCodeLocation = [NSURL NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
RCTRootView *rootView = RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL : jsCodeLocation [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
moduleName : @"RNHighScores" moduleName: @"RNHighScores"
initialProperties : initialProperties:
@{ @{
@"scores" : @[ @"scores" : @[
@{ @{
@ -404,7 +404,7 @@ First `import` the `RCTRootView` header.
} }
] ]
} }
launchOptions : nil]; launchOptions: nil];
UIViewController *vc = [[UIViewController alloc] init]; UIViewController *vc = [[UIViewController alloc] init];
vc.view = rootView; vc.view = rootView;
[self presentViewController:vc animated:YES completion:nil]; [self presentViewController:vc animated:YES completion:nil];
@ -417,13 +417,13 @@ First `import` the `RCTRootView` header.
First `import` the `React` library. First `import` the `React` library.
``` ```javascript
import React import React
``` ```
> The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data. > The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data.
``` ```swift
@IBAction func highScoreButtonTapped(sender : UIButton) { @IBAction func highScoreButtonTapped(sender : UIButton) {
NSLog("Hello") NSLog("Hello")
let jsCodeLocation = URL(string: "http://localhost:8081/index.ios.bundle?platform=ios") let jsCodeLocation = URL(string: "http://localhost:8081/index.ios.bundle?platform=ios")
@ -494,7 +494,7 @@ Apple has blocked implicit cleartext HTTP resource loading. So we need to add th
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project: To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
```bash ```
$ npm start $ npm start
``` ```
@ -502,7 +502,7 @@ $ npm start
If you are using Xcode or your favorite editor, build and run your native iOS application as normal. Alternatively, you can run the app from the command line using: If you are using Xcode or your favorite editor, build and run your native iOS application as normal. Alternatively, you can run the app from the command line using:
```bash ```
# From the root of your project # From the root of your project
$ react-native run-ios $ react-native run-ios
``` ```
@ -593,7 +593,7 @@ First, create an empty `index.android.js` file in the root of your React Native
In your `index.android.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>`: In your `index.android.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>`:
```js ```javascript
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
@ -692,11 +692,13 @@ public class MyReactActivity extends Activity implements DefaultHardwareBackBtnH
} }
} }
``` ```
> If you are using a starter kit for React Native, replace the "HelloWorld" string with the one in your index.android.js file (its the first argument to the `AppRegistry.registerComponent()` method). > If you are using a starter kit for React Native, replace the "HelloWorld" string with the one in your index.android.js file (its the first argument to the `AppRegistry.registerComponent()` method).
If you are using Android Studio, use `Alt + Enter` to add all missing imports in your MyReactActivity class. Be careful to use your packages `BuildConfig` and not the one from the `...facebook...` package. If you are using Android Studio, use `Alt + Enter` to add all missing imports in your MyReactActivity class. Be careful to use your packages `BuildConfig` and not the one from the `...facebook...` package.
We need set the theme of `MyReactActivity` to `Theme.AppCompat.Light.NoActionBar` because some components rely on this theme. We need set the theme of `MyReactActivity` to `Theme.AppCompat.Light.NoActionBar` because some components rely on this theme.
```xml ```xml
<activity <activity
android:name=".MyReactActivity" android:name=".MyReactActivity"
@ -776,7 +778,7 @@ You have now done all the basic steps to integrate React Native with your curren
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project: To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
```bash ```
$ npm start $ npm start
``` ```
@ -790,11 +792,13 @@ Once you reach your React-powered activity inside the app, it should load the Ja
### Creating a release build in Android Studio ### Creating a release build in Android Studio
You can use Android Studio to create your release builds too! Its as easy as creating release builds of your previously-existing native Android app. Theres just one additional step, which youll have to do before every release build. You need to execute the following to create a React Native bundle, whichll be included with your native Android app: You can use Android Studio to create your release builds too! Its as easy as creating release builds of your previously-existing native Android app. Theres just one additional step, which youll have to do before every release build. You need to execute the following to create a React Native bundle, which will be included with your native Android app:
$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/ ```
$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
```
Dont forget to replace the paths with correct ones and create the assets folder if it doesnt exist! > Dont forget to replace the paths with correct ones and create the assets folder if it doesnt exist.
Now just create a release build of your native app from within Android Studio as usual and you should be good to go! Now just create a release build of your native app from within Android Studio as usual and you should be good to go!
@ -809,7 +813,6 @@ function displayTab(type, value) {
var container = document.getElementsByTagName('block')[0].parentNode; var container = document.getElementsByTagName('block')[0].parentNode;
container.className = 'display-' + type + '-' + value + ' ' + container.className = 'display-' + type + '-' + value + ' ' +
container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), ''); container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), '');
console.log(container.className);
event && event.preventDefault(); event && event.preventDefault();
} }
</script> </script>

Просмотреть файл

@ -25,7 +25,7 @@ Vending a view is simple:
- Add the `RCT_EXPORT_MODULE()` marker macro. - Add the `RCT_EXPORT_MODULE()` marker macro.
- Implement the `-(UIView *)view` method. - Implement the `-(UIView *)view` method.
```objective-c ```objectivec
// RNTMapManager.m // RNTMapManager.m
#import <MapKit/MapKit.h> #import <MapKit/MapKit.h>
@ -66,7 +66,7 @@ This is now a fully-functioning native map view component in JavaScript, complet
The first thing we can do to make this component more usable is to bridge over some native properties. Let's say we want to be able to disable pitch control and specify the visible region. Disabling pitch is a simple boolean, so we add this one line: The first thing we can do to make this component more usable is to bridge over some native properties. Let's say we want to be able to disable pitch control and specify the visible region. Disabling pitch is a simple boolean, so we add this one line:
```objective-c ```objectivec
// RNTMapManager.m // RNTMapManager.m
RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL)
``` ```
@ -113,7 +113,7 @@ Now we have a nicely documented wrapper component that is easy to work with. No
Next, let's add the more complex `region` prop. We start by adding the native code: Next, let's add the more complex `region` prop. We start by adding the native code:
```objective-c ```objectivec
// RNTMapManager.m // RNTMapManager.m
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RNTMap) RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RNTMap)
{ {
@ -125,7 +125,7 @@ Ok, this is more complicated than the simple `BOOL` case we had before. Now we
You could write any conversion function you want for your view - here is the implementation for `MKCoordinateRegion` via two categories on `RCTConvert`: You could write any conversion function you want for your view - here is the implementation for `MKCoordinateRegion` via two categories on `RCTConvert`:
```objective-c ```objectivec
@implementation RCTConvert(CoreLocation) @implementation RCTConvert(CoreLocation)
RCT_CONVERTER(CLLocationDegrees, CLLocationDegrees, doubleValue); RCT_CONVERTER(CLLocationDegrees, CLLocationDegrees, doubleValue);
@ -229,7 +229,7 @@ var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, {
So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region? The key is to declare an event handler property on `RNTMapManager`, make it a delegate for all the views it vends, and forward events to JS by calling the event handler block from the native view. This looks like so (simplified from the full implementation): So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region? The key is to declare an event handler property on `RNTMapManager`, make it a delegate for all the views it vends, and forward events to JS by calling the event handler block from the native view. This looks like so (simplified from the full implementation):
```objective-c ```objectivec
// RNTMap.h // RNTMap.h
#import <MapKit/MapKit.h> #import <MapKit/MapKit.h>
@ -243,7 +243,7 @@ So now we have a native map component that we can control easily from JS, but ho
@end @end
``` ```
```objective-c ```objectivec
// RNTMap.m // RNTMap.m
#import "RNTMap.h" #import "RNTMap.h"
@ -253,7 +253,7 @@ So now we have a native map component that we can control easily from JS, but ho
@end @end
``` ```
```objective-c ```objectivec
// RNTMapManager.m // RNTMapManager.m
#import "RNTMapManager.h" #import "RNTMapManager.h"
@ -383,7 +383,7 @@ var styles = StyleSheet.create({
The `RCTDatePickerIOSConsts` constants are exported from native by grabbing the actual frame of the native component like so: The `RCTDatePickerIOSConsts` constants are exported from native by grabbing the actual frame of the native component like so:
```objective-c ```objectivec
// RCTDatePickerManager.m // RCTDatePickerManager.m
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport

Просмотреть файл

@ -21,7 +21,7 @@ This guide will use the [iOS Calendar API](https://developer.apple.com/library/m
A native module is just an Objective-C class that implements the `RCTBridgeModule` protocol. If you are wondering, RCT is an abbreviation of ReaCT. A native module is just an Objective-C class that implements the `RCTBridgeModule` protocol. If you are wondering, RCT is an abbreviation of ReaCT.
```objective-c ```objectivec
// CalendarManager.h // CalendarManager.h
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
@ -31,7 +31,7 @@ A native module is just an Objective-C class that implements the `RCTBridgeModul
In addition to implementing the `RCTBridgeModule` protocol, your class must also include the `RCT_EXPORT_MODULE()` macro. This takes an optional argument that specifies the name that the module will be accessible as in your JavaScript code (more on this later). If you do not specify a name, the JavaScript module name will match the Objective-C class name. In addition to implementing the `RCTBridgeModule` protocol, your class must also include the `RCT_EXPORT_MODULE()` macro. This takes an optional argument that specifies the name that the module will be accessible as in your JavaScript code (more on this later). If you do not specify a name, the JavaScript module name will match the Objective-C class name.
```objective-c ```objectivec
// CalendarManager.m // CalendarManager.m
@implementation CalendarManager @implementation CalendarManager
@ -46,7 +46,7 @@ RCT_EXPORT_MODULE();
React Native will not expose any methods of `CalendarManager` to JavaScript unless explicitly told to. This is done using the `RCT_EXPORT_METHOD()` macro: React Native will not expose any methods of `CalendarManager` to JavaScript unless explicitly told to. This is done using the `RCT_EXPORT_METHOD()` macro:
```objective-c ```objectivec
#import "CalendarManager.h" #import "CalendarManager.h"
#import <React/RCTLog.h> #import <React/RCTLog.h>
@ -89,7 +89,7 @@ But it also works with any type that is supported by the `RCTConvert` class (see
In our `CalendarManager` example, we need to pass the event date to the native method. We can't send JavaScript Date objects over the bridge, so we need to convert the date to a string or number. We could write our native function like this: In our `CalendarManager` example, we need to pass the event date to the native method. We can't send JavaScript Date objects over the bridge, so we need to convert the date to a string or number. We could write our native function like this:
```objective-c ```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)secondsSinceUnixEpoch) RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)secondsSinceUnixEpoch)
{ {
NSDate *date = [RCTConvert NSDate:secondsSinceUnixEpoch]; NSDate *date = [RCTConvert NSDate:secondsSinceUnixEpoch];
@ -98,7 +98,7 @@ RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(
or like this: or like this:
```objective-c ```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSString *)ISO8601DateString) RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSString *)ISO8601DateString)
{ {
NSDate *date = [RCTConvert NSDate:ISO8601DateString]; NSDate *date = [RCTConvert NSDate:ISO8601DateString];
@ -107,7 +107,7 @@ RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(
But by using the automatic type conversion feature, we can skip the manual conversion step completely, and just write: But by using the automatic type conversion feature, we can skip the manual conversion step completely, and just write:
```objective-c ```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSDate *)date) RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSDate *)date)
{ {
// Date is ready to use! // Date is ready to use!
@ -130,7 +130,7 @@ And both values would get converted correctly to the native `NSDate`. A bad val
As `CalendarManager.addEvent` method gets more and more complex, the number of arguments will grow. Some of them might be optional. In this case it's worth considering changing the API a little bit to accept a dictionary of event attributes, like this: As `CalendarManager.addEvent` method gets more and more complex, the number of arguments will grow. Some of them might be optional. In this case it's worth considering changing the API a little bit to accept a dictionary of event attributes, like this:
```objective-c ```objectivec
#import <React/RCTConvert.h> #import <React/RCTConvert.h>
RCT_EXPORT_METHOD(addEvent:(NSString *)name details:(NSDictionary *)details) RCT_EXPORT_METHOD(addEvent:(NSString *)name details:(NSDictionary *)details)
@ -163,7 +163,7 @@ CalendarManager.addEvent('Birthday Party', {
Native modules also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript. Native modules also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript.
```objective-c ```objectivec
RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback)
{ {
NSArray *events = ... NSArray *events = ...
@ -193,7 +193,7 @@ Native modules can also fulfill a promise, which can simplify your code, especia
Refactoring the above code to use a promise instead of callbacks looks like this: Refactoring the above code to use a promise instead of callbacks looks like this:
```objective-c ```objectivec
RCT_REMAP_METHOD(findEvents, RCT_REMAP_METHOD(findEvents,
findEventsWithResolver:(RCTPromiseResolveBlock)resolve findEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) rejecter:(RCTPromiseRejectBlock)reject)
@ -228,7 +228,7 @@ updateEvents();
The native module should not have any assumptions about what thread it is being called on. React Native invokes native modules methods on a separate serial GCD queue, but this is an implementation detail and might change. The `- (dispatch_queue_t)methodQueue` method allows the native module to specify which queue its methods should be run on. For example, if it needs to use a main-thread-only iOS API, it should specify this via: The native module should not have any assumptions about what thread it is being called on. React Native invokes native modules methods on a separate serial GCD queue, but this is an implementation detail and might change. The `- (dispatch_queue_t)methodQueue` method allows the native module to specify which queue its methods should be run on. For example, if it needs to use a main-thread-only iOS API, it should specify this via:
```objective-c ```objectivec
- (dispatch_queue_t)methodQueue - (dispatch_queue_t)methodQueue
{ {
return dispatch_get_main_queue(); return dispatch_get_main_queue();
@ -237,7 +237,7 @@ The native module should not have any assumptions about what thread it is being
Similarly, if an operation may take a long time to complete, the native module should not block and can specify it's own queue to run operations on. For example, the `RCTAsyncLocalStorage` module creates it's own queue so the React queue isn't blocked waiting on potentially slow disk access: Similarly, if an operation may take a long time to complete, the native module should not block and can specify it's own queue to run operations on. For example, the `RCTAsyncLocalStorage` module creates it's own queue so the React queue isn't blocked waiting on potentially slow disk access:
```objective-c ```objectivec
- (dispatch_queue_t)methodQueue - (dispatch_queue_t)methodQueue
{ {
return dispatch_queue_create("com.facebook.React.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL); return dispatch_queue_create("com.facebook.React.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
@ -246,7 +246,7 @@ Similarly, if an operation may take a long time to complete, the native module s
The specified `methodQueue` will be shared by all of the methods in your module. If *just one* of your methods is long-running (or needs to be run on a different queue than the others for some reason), you can use `dispatch_async` inside the method to perform that particular method's code on another queue, without affecting the others: The specified `methodQueue` will be shared by all of the methods in your module. If *just one* of your methods is long-running (or needs to be run on a different queue than the others for some reason), you can use `dispatch_async` inside the method to perform that particular method's code on another queue, without affecting the others:
```objective-c ```objectivec
RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock)callback)
{ {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@ -267,7 +267,7 @@ The bridge initializes any registered RCTBridgeModules automatically, however yo
You can do this by creating a class that implements the RCTBridgeDelegate Protocol, initializing an RCTBridge with the delegate as an argument and initialising a RCTRootView with the initialized bridge. You can do this by creating a class that implements the RCTBridgeDelegate Protocol, initializing an RCTBridge with the delegate as an argument and initialising a RCTRootView with the initialized bridge.
```objective-c ```objectivec
id<RCTBridgeDelegate> moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init]; id<RCTBridgeDelegate> moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil]; RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil];
@ -282,7 +282,7 @@ RCTRootView *rootView = [[RCTRootView alloc]
A native module can export constants that are immediately available to JavaScript at runtime. This is useful for communicating static data that would otherwise require a round-trip through the bridge. A native module can export constants that are immediately available to JavaScript at runtime. This is useful for communicating static data that would otherwise require a round-trip through the bridge.
```objective-c ```objectivec
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport
{ {
return @{ @"firstDayOfTheWeek": @"Monday" }; return @{ @"firstDayOfTheWeek": @"Monday" };
@ -303,7 +303,7 @@ Enums that are defined via `NS_ENUM` cannot be used as method arguments without
In order to export the following `NS_ENUM` definition: In order to export the following `NS_ENUM` definition:
```objc ```objectivec
typedef NS_ENUM(NSInteger, UIStatusBarAnimation) { typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
UIStatusBarAnimationNone, UIStatusBarAnimationNone,
UIStatusBarAnimationFade, UIStatusBarAnimationFade,
@ -313,7 +313,7 @@ typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
You must create a class extension of RCTConvert like so: You must create a class extension of RCTConvert like so:
```objc ```objectivec
@implementation RCTConvert (StatusBarAnimation) @implementation RCTConvert (StatusBarAnimation)
RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone), RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
@"statusBarAnimationFade" : @(UIStatusBarAnimationFade), @"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
@ -324,7 +324,7 @@ You must create a class extension of RCTConvert like so:
You can then define methods and export your enum constants like this: You can then define methods and export your enum constants like this:
```objc ```objectivec
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport
{ {
return @{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone), return @{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
@ -343,7 +343,7 @@ Your enum will then be automatically unwrapped using the selector provided (`int
The native module can signal events to JavaScript without being invoked directly. The preferred way to do this is to subclass `RCTEventEmitter`, implement `suppportEvents` and call `self sendEventWithName`: The native module can signal events to JavaScript without being invoked directly. The preferred way to do this is to subclass `RCTEventEmitter`, implement `suppportEvents` and call `self sendEventWithName`:
```objective-c ```objectivec
// CalendarManager.h // CalendarManager.h
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h> #import <React/RCTEventEmitter.h>
@ -353,7 +353,7 @@ The native module can signal events to JavaScript without being invoked directly
@end @end
``` ```
```objective-c ```objectivec
// CalendarManager.m // CalendarManager.m
#import "CalendarManager.h" #import "CalendarManager.h"
@ -396,7 +396,7 @@ For more examples of sending events to JavaScript, see [`RCTLocationObserver`](h
### Optimizing for zero listeners ### Optimizing for zero listeners
You will receive a warning if you expend resources unnecessarily by emitting an event while there are no listeners. To avoid this, and to optimize your module's workload (e.g. by unsubscribing from upstream notifications or pausing background tasks), you can override `startObserving` and `stopObserving` in your `RCTEventEmitter` subclass. You will receive a warning if you expend resources unnecessarily by emitting an event while there are no listeners. To avoid this, and to optimize your module's workload (e.g. by unsubscribing from upstream notifications or pausing background tasks), you can override `startObserving` and `stopObserving` in your `RCTEventEmitter` subclass.
```objective-c ```objectivec
@implementation CalendarManager @implementation CalendarManager
{ {
bool hasListeners; bool hasListeners;
@ -446,7 +446,7 @@ class CalendarManager: NSObject {
Then create a private implementation file that will register the required information with the React Native bridge: Then create a private implementation file that will register the required information with the React Native bridge:
```objc ```objectivec
// CalendarManagerBridge.m // CalendarManagerBridge.m
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
@ -459,7 +459,7 @@ RCT_EXTERN_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(
For those of you new to Swift and Objective-C, whenever you [mix the two languages in an iOS project](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html), you will also need an additional bridging file, known as a bridging header, to expose the Objective-C files to Swift. Xcode will offer to create this header file for you if you add your Swift file to your app through the Xcode `File>New File` menu option. You will need to import `RCTBridgeModule.h` in this header file. For those of you new to Swift and Objective-C, whenever you [mix the two languages in an iOS project](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html), you will also need an additional bridging file, known as a bridging header, to expose the Objective-C files to Swift. Xcode will offer to create this header file for you if you add your Swift file to your app through the Xcode `File>New File` menu option. You will need to import `RCTBridgeModule.h` in this header file.
```objc ```objectivec
// CalendarManager-Bridging-Header.h // CalendarManager-Bridging-Header.h
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
``` ```

Просмотреть файл

@ -35,40 +35,41 @@ var block = {
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
table: noop, table: noop,
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
text: /^[^\n]+/ text: /^[^\n]+/,
}; };
block.bullet = /(?:[*+-]|\d+\.)/; block.bullet = /(?:[*+-]|\d+\.)/;
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
block.item = replace(block.item, 'gm') block.item = replace(block.item, 'gm')(
(/bull/g, block.bullet) /bull/g,
(); block.bullet
)();
block.list = replace(block.list) block.list = replace(block.list)(/bull/g, block.bullet)(
(/bull/g, block.bullet) 'hr',
('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/) /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/
(); )();
block._tag = '(?!(?:' block._tag = '(?!(?:' +
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' +
+ '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' +
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b'; '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b';
block.html = replace(block.html) block.html = replace(block.html)(
('comment', /<!--[\s\S]*?-->/) 'comment',
('closed', /<(tag)[\s\S]+?<\/\1>/) /<!--[\s\S]*?-->/
('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/) )('closed', /<(tag)[\s\S]+?<\/\1>/)(
(/tag/g, block._tag) 'closing',
(); /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/
)(/tag/g, block._tag)();
block.paragraph = replace(block.paragraph) block.paragraph = replace(block.paragraph)('hr', block.hr)(
('hr', block.hr) 'heading',
('heading', block.heading) block.heading
('lheading', block.lheading) )('lheading', block.lheading)(
('blockquote', block.blockquote) 'blockquote',
('tag', '<' + block._tag) block.blockquote
('def', block.def) )('tag', '<' + block._tag)('def', block.def)();
();
/** /**
* Normal Block Grammar * Normal Block Grammar
@ -82,12 +83,15 @@ block.normal = merge({}, block);
block.gfm = merge({}, block.normal, { block.gfm = merge({}, block.normal, {
fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
paragraph: /^/ paragraph: /^/,
}); });
block.gfm.paragraph = replace(block.paragraph) block.gfm.paragraph = replace(block.paragraph)(
('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') '(?!',
(); '(?!' +
block.gfm.fences.source.replace('\\1', '\\2') +
'|'
)();
/** /**
* GFM + Tables Block Grammar * GFM + Tables Block Grammar
@ -95,7 +99,7 @@ block.gfm.paragraph = replace(block.paragraph)
block.tables = merge({}, block.gfm, { block.tables = merge({}, block.gfm, {
nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/,
}); });
/** /**
@ -151,59 +155,59 @@ Lexer.prototype.lex = function(src) {
*/ */
Lexer.prototype.token = function(src, top) { Lexer.prototype.token = function(src, top) {
var src = src.replace(/^ +$/gm, '') var src = src.replace(/^ +$/gm, ''),
, next next,
, loose loose,
, cap cap,
, bull bull,
, b b,
, item item,
, space space,
, i i,
, l; l;
while (src) { while (src) {
// newline // newline
if (cap = this.rules.newline.exec(src)) { if ((cap = this.rules.newline.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
if (cap[0].length > 1) { if (cap[0].length > 1) {
this.tokens.push({ this.tokens.push({
type: 'space' type: 'space',
}); });
} }
} }
// code // code
if (cap = this.rules.code.exec(src)) { if ((cap = this.rules.code.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
cap = cap[0].replace(/^ {4}/gm, ''); cap = cap[0].replace(/^ {4}/gm, '');
this.tokens.push({ this.tokens.push({
type: 'code', type: 'code',
text: !this.options.pedantic text: !this.options.pedantic
? cap.replace(/\n+$/, '') ? cap.replace(/\n+$/, '')
: cap : cap,
}); });
continue; continue;
} }
// fences (gfm) // fences (gfm)
if (cap = this.rules.fences.exec(src)) { if ((cap = this.rules.fences.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'code', type: 'code',
lang: cap[2], lang: cap[2],
text: cap[3] text: cap[3],
}); });
continue; continue;
} }
// heading // heading
if (cap = this.rules.heading.exec(src)) { if ((cap = this.rules.heading.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'heading', type: 'heading',
depth: cap[1].length, depth: cap[1].length,
text: cap[2] text: cap[2],
}); });
continue; continue;
} }
@ -214,9 +218,13 @@ Lexer.prototype.token = function(src, top) {
item = { item = {
type: 'table', type: 'table',
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), header: cap[1]
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), .replace(/^ *| *\| *$/g, '')
cells: cap[3].replace(/\n$/, '').split('\n') .split(/ *\| */),
align: cap[2]
.replace(/^ *|\| *$/g, '')
.split(/ *\| */),
cells: cap[3].replace(/\n$/, '').split('\n'),
}; };
for (i = 0; i < item.align.length; i++) { for (i = 0; i < item.align.length; i++) {
@ -241,31 +249,31 @@ Lexer.prototype.token = function(src, top) {
} }
// lheading // lheading
if (cap = this.rules.lheading.exec(src)) { if ((cap = this.rules.lheading.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'heading', type: 'heading',
depth: cap[2] === '=' ? 1 : 2, depth: cap[2] === '=' ? 1 : 2,
text: cap[1] text: cap[1],
}); });
continue; continue;
} }
// hr // hr
if (cap = this.rules.hr.exec(src)) { if ((cap = this.rules.hr.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'hr' type: 'hr',
}); });
continue; continue;
} }
// blockquote // blockquote
if (cap = this.rules.blockquote.exec(src)) { if ((cap = this.rules.blockquote.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'blockquote_start' type: 'blockquote_start',
}); });
cap = cap[0].replace(/^ *> ?/gm, ''); cap = cap[0].replace(/^ *> ?/gm, '');
@ -276,20 +284,20 @@ Lexer.prototype.token = function(src, top) {
this.token(cap, top); this.token(cap, top);
this.tokens.push({ this.tokens.push({
type: 'blockquote_end' type: 'blockquote_end',
}); });
continue; continue;
} }
// list // list
if (cap = this.rules.list.exec(src)) { if ((cap = this.rules.list.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
bull = cap[2]; bull = cap[2];
this.tokens.push({ this.tokens.push({
type: 'list_start', type: 'list_start',
ordered: bull.length > 1 ordered: bull.length > 1,
}); });
// Get each top-level item. // Get each top-level item.
@ -312,15 +320,20 @@ Lexer.prototype.token = function(src, top) {
if (~item.indexOf('\n ')) { if (~item.indexOf('\n ')) {
space -= item.length; space -= item.length;
item = !this.options.pedantic item = !this.options.pedantic
? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') ? item.replace(
new RegExp('^ {1,' + space + '}', 'gm'),
''
)
: item.replace(/^ {1,4}/gm, ''); : item.replace(/^ {1,4}/gm, '');
} }
// Determine whether the next list item belongs here. // Determine whether the next list item belongs here.
// Backpedal if it does not belong in this list. // Backpedal if it does not belong in this list.
if (this.options.smartLists && i !== l - 1) { if (this.options.smartLists && i !== l - 1) {
b = block.bullet.exec(cap[i+1])[0]; b = block.bullet.exec(cap[i + 1])[0];
if (bull !== b && !(bull.length > 1 && b.length > 1)) { if (
bull !== b && !(bull.length > 1 && b.length > 1)
) {
src = cap.slice(i + 1).join('\n') + src; src = cap.slice(i + 1).join('\n') + src;
i = l - 1; i = l - 1;
} }
@ -331,40 +344,38 @@ Lexer.prototype.token = function(src, top) {
// for discount behavior. // for discount behavior.
loose = next || /\n\n(?!\s*$)/.test(item); loose = next || /\n\n(?!\s*$)/.test(item);
if (i !== l - 1) { if (i !== l - 1) {
next = item[item.length-1] === '\n'; next = item[item.length - 1] === '\n';
if (!loose) loose = next; if (!loose) loose = next;
} }
this.tokens.push({ this.tokens.push({
type: loose type: loose
? 'loose_item_start' ? 'loose_item_start'
: 'list_item_start' : 'list_item_start',
}); });
// Recurse. // Recurse.
this.token(item, false); this.token(item, false);
this.tokens.push({ this.tokens.push({
type: 'list_item_end' type: 'list_item_end',
}); });
} }
this.tokens.push({ this.tokens.push({
type: 'list_end' type: 'list_end',
}); });
continue; continue;
} }
// html // html
if (cap = this.rules.html.exec(src)) { if ((cap = this.rules.html.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: this.options.sanitize type: this.options.sanitize ? 'paragraph' : 'html',
? 'paragraph'
: 'html',
pre: cap[1] === 'pre', pre: cap[1] === 'pre',
text: cap[0] text: cap[0],
}); });
continue; continue;
} }
@ -374,7 +385,7 @@ Lexer.prototype.token = function(src, top) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.links[cap[1].toLowerCase()] = { this.tokens.links[cap[1].toLowerCase()] = {
href: cap[2], href: cap[2],
title: cap[3] title: cap[3],
}; };
continue; continue;
} }
@ -385,9 +396,15 @@ Lexer.prototype.token = function(src, top) {
item = { item = {
type: 'table', type: 'table',
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), header: cap[1]
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), .replace(/^ *| *\| *$/g, '')
cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') .split(/ *\| */),
align: cap[2]
.replace(/^ *|\| *$/g, '')
.split(/ *\| */),
cells: cap[3]
.replace(/(?: *\| *)?\n$/, '')
.split('\n'),
}; };
for (i = 0; i < item.align.length; i++) { for (i = 0; i < item.align.length; i++) {
@ -418,27 +435,28 @@ Lexer.prototype.token = function(src, top) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'paragraph', type: 'paragraph',
text: cap[1][cap[1].length-1] === '\n' text: cap[1][cap[1].length - 1] === '\n'
? cap[1].slice(0, -1) ? cap[1].slice(0, -1)
: cap[1] : cap[1],
}); });
continue; continue;
} }
// text // text
if (cap = this.rules.text.exec(src)) { if ((cap = this.rules.text.exec(src))) {
// Top-level should never reach here. // Top-level should never reach here.
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'text', type: 'text',
text: cap[0] text: cap[0],
}); });
continue; continue;
} }
if (src) { if (src) {
throw new throw new Error(
Error('Infinite loop on byte: ' + src.charCodeAt(0)); 'Infinite loop on byte: ' + src.charCodeAt(0)
);
} }
} }
@ -462,20 +480,21 @@ var inline = {
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
br: /^ {2,}\n(?!\s*$)/, br: /^ {2,}\n(?!\s*$)/,
del: noop, del: noop,
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/,
}; };
inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/; inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;
inline._href = /\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/; inline._href = /\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
inline.link = replace(inline.link) inline.link = replace(inline.link)(
('inside', inline._inside) 'inside',
('href', inline._href) inline._inside
(); )('href', inline._href)();
inline.reflink = replace(inline.reflink) inline.reflink = replace(inline.reflink)(
('inside', inline._inside) 'inside',
(); inline._inside
)();
/** /**
* Normal Inline Grammar * Normal Inline Grammar
@ -489,7 +508,7 @@ inline.normal = merge({}, inline);
inline.pedantic = merge({}, inline.normal, { inline.pedantic = merge({}, inline.normal, {
strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
}); });
/** /**
@ -500,10 +519,10 @@ inline.gfm = merge({}, inline.normal, {
escape: replace(inline.escape)('])', '~|])')(), escape: replace(inline.escape)('])', '~|])')(),
url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
del: /^~~(?=\S)([\s\S]*?\S)~~/, del: /^~~(?=\S)([\s\S]*?\S)~~/,
text: replace(inline.text) text: replace(inline.text)(']|', '~]|')(
(']|', '~]|') '|',
('|', '|https?://|') '|https?://|'
() )(),
}); });
/** /**
@ -512,7 +531,7 @@ inline.gfm = merge({}, inline.normal, {
inline.breaks = merge({}, inline.gfm, { inline.breaks = merge({}, inline.gfm, {
br: replace(inline.br)('{2,}', '*')(), br: replace(inline.br)('{2,}', '*')(),
text: replace(inline.gfm.text)('{2,}', '*')() text: replace(inline.gfm.text)('{2,}', '*')(),
}); });
/** /**
@ -525,8 +544,9 @@ function InlineLexer(links, options) {
this.rules = inline.normal; this.rules = inline.normal;
if (!this.links) { if (!this.links) {
throw new throw new Error(
Error('Tokens array requires a `links` property.'); 'Tokens array requires a `links` property.'
);
} }
if (this.options.gfm) { if (this.options.gfm) {
@ -560,22 +580,18 @@ InlineLexer.output = function(src, links, options) {
*/ */
InlineLexer.prototype.output = function(src) { InlineLexer.prototype.output = function(src) {
var out = [] var out = [], link, text, href, cap;
, link
, text
, href
, cap;
while (src) { while (src) {
// escape // escape
if (cap = this.rules.escape.exec(src)) { if ((cap = this.rules.escape.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(cap[1]); out.push(cap[1]);
continue; continue;
} }
// autolink // autolink
if (cap = this.rules.autolink.exec(src)) { if ((cap = this.rules.autolink.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
if (cap[2] === '@') { if (cap[2] === '@') {
text = cap[1][6] === ':' text = cap[1][6] === ':'
@ -586,26 +602,35 @@ InlineLexer.prototype.output = function(src) {
text = cap[1]; text = cap[1];
href = text; href = text;
} }
out.push(React.DOM.a({href: this.sanitizeUrl(href)}, text)); out.push(
React.DOM.a({ href: this.sanitizeUrl(href) }, text)
);
continue; continue;
} }
// url (gfm) // url (gfm)
if (cap = this.rules.url.exec(src)) { if ((cap = this.rules.url.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
text = cap[1]; text = cap[1];
href = text; href = text;
out.push(React.DOM.a({href: this.sanitizeUrl(href)}, text)); out.push(
React.DOM.a({ href: this.sanitizeUrl(href) }, text)
);
continue; continue;
} }
// tag // tag
if (cap = this.rules.tag.exec(src)) { if ((cap = this.rules.tag.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
var color = cap[0].match('<color ([^ ]+) />'); var color = cap[0].match('<color ([^ ]+) />');
if (color) { if (color) {
out.push(React.DOM.span({className: 'color', style: {backgroundColor: color[1]}})); out.push(
React.DOM.span({
className: 'color',
style: { backgroundColor: color[1] },
})
);
continue; continue;
} }
@ -615,18 +640,22 @@ InlineLexer.prototype.output = function(src) {
} }
// link // link
if (cap = this.rules.link.exec(src)) { if ((cap = this.rules.link.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(this.outputLink(cap, { out.push(
this.outputLink(cap, {
href: cap[2], href: cap[2],
title: cap[3] title: cap[3],
})); })
);
continue; continue;
} }
// reflink, nolink // reflink, nolink
if ((cap = this.rules.reflink.exec(src)) if (
|| (cap = this.rules.nolink.exec(src))) { (cap = this.rules.reflink.exec(src)) ||
(cap = this.rules.nolink.exec(src))
) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
link = (cap[2] || cap[1]).replace(/\s+/g, ' '); link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
link = this.links[link.toLowerCase()]; link = this.links[link.toLowerCase()];
@ -640,50 +669,58 @@ InlineLexer.prototype.output = function(src) {
} }
// strong // strong
if (cap = this.rules.strong.exec(src)) { if ((cap = this.rules.strong.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.strong(null, this.output(cap[2] || cap[1]))); out.push(
React.DOM.strong(
null,
this.output(cap[2] || cap[1])
)
);
continue; continue;
} }
// em // em
if (cap = this.rules.em.exec(src)) { if ((cap = this.rules.em.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.em(null, this.output(cap[2] || cap[1]))); out.push(
React.DOM.em(null, this.output(cap[2] || cap[1]))
);
continue; continue;
} }
// code // code
if (cap = this.rules.code.exec(src)) { if ((cap = this.rules.code.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.code(null, cap[2])); out.push(React.DOM.code(null, cap[2]));
continue; continue;
} }
// br // br
if (cap = this.rules.br.exec(src)) { if ((cap = this.rules.br.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.br(null, null)); out.push(React.DOM.br(null, null));
continue; continue;
} }
// del (gfm) // del (gfm)
if (cap = this.rules.del.exec(src)) { if ((cap = this.rules.del.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.del(null, this.output(cap[1]))); out.push(React.DOM.del(null, this.output(cap[1])));
continue; continue;
} }
// text // text
if (cap = this.rules.text.exec(src)) { if ((cap = this.rules.text.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(this.smartypants(cap[0])); out.push(this.smartypants(cap[0]));
continue; continue;
} }
if (src) { if (src) {
throw new throw new Error(
Error('Infinite loop on byte: ' + src.charCodeAt(0)); 'Infinite loop on byte: ' + src.charCodeAt(0)
);
} }
} }
@ -716,21 +753,26 @@ InlineLexer.prototype.sanitizeUrl = function(url) {
InlineLexer.prototype.outputLink = function(cap, link) { InlineLexer.prototype.outputLink = function(cap, link) {
if (cap[0][0] !== '!') { if (cap[0][0] !== '!') {
var shouldOpenInNewWindow = var shouldOpenInNewWindow = link.href.charAt(0) !==
link.href.charAt(0) !== '/' '/' && link.href.charAt(0) !== '#';
&& link.href.charAt(0) !== '#';
return React.DOM.a({ return React.DOM.a(
{
href: this.sanitizeUrl(link.href), href: this.sanitizeUrl(link.href),
title: link.title, title: link.title,
target: shouldOpenInNewWindow ? '_blank' : '' target: shouldOpenInNewWindow ? '_blank' : '',
}, this.output(cap[1])); },
this.output(cap[1])
);
} else { } else {
return React.DOM.img({ return React.DOM.img(
{
src: this.sanitizeUrl(link.href), src: this.sanitizeUrl(link.href),
alt: cap[1], alt: cap[1],
title: link.title title: link.title,
}, null); },
null
);
} }
}; };
@ -787,7 +829,7 @@ Parser.prototype.parse = function(src) {
*/ */
Parser.prototype.next = function() { Parser.prototype.next = function() {
return this.token = this.tokens.pop(); return (this.token = this.tokens.pop());
}; };
/** /**
@ -795,7 +837,7 @@ Parser.prototype.next = function() {
*/ */
Parser.prototype.peek = function() { Parser.prototype.peek = function() {
return this.tokens[this.tokens.length-1] || 0; return this.tokens[this.tokens.length - 1] || 0;
}; };
/** /**
@ -828,61 +870,83 @@ Parser.prototype.tok = function() {
return ( return (
<Header <Header
level={this.token.depth} level={this.token.depth}
toSlug={this.token.text}> toSlug={this.token.text}
>
{this.inline.output(this.token.text)} {this.inline.output(this.token.text)}
</Header> </Header>
); );
} }
case 'code': { case 'code': {
var lang = this.token.lang var lang = this.token.lang, text = this.token.text;
, text = this.token.text;
if (lang && lang.indexOf('ReactNativeWebPlayer') === 0) { if (
lang && lang.indexOf('ReactNativeWebPlayer') === 0
) {
return ( return (
<WebPlayer params={lang.split('?')[1]}>{text}</WebPlayer> <WebPlayer params={lang.split('?')[1]}>
{text}
</WebPlayer>
); );
} }
if (lang && lang.indexOf('SnackPlayer') === 0) { if (lang && lang.indexOf('SnackPlayer') === 0) {
return ( return (
<SnackPlayer params={lang.split('?')[1]}>{text}</SnackPlayer> <SnackPlayer params={lang.split('?')[1]}>
{text}
</SnackPlayer>
); );
} }
if (lang) {
return <Prism language={lang}>{text}</Prism>;
}
return <Prism>{text}</Prism>; return <Prism>{text}</Prism>;
} }
case 'table': { case 'table': {
var table = [] var table = [],
, body = [] body = [],
, row = [] row = [],
, heading heading,
, i i,
, cells cells,
, j; j;
// header // header
for (i = 0; i < this.token.header.length; i++) { for (i = 0; i < this.token.header.length; i++) {
heading = this.inline.output(this.token.header[i]); heading = this.inline.output(this.token.header[i]);
row.push(React.DOM.th( row.push(
React.DOM.th(
this.token.align[i] this.token.align[i]
? {style: {textAlign: this.token.align[i]}} ? {
style: { textAlign: this.token.align[i] },
}
: null, : null,
heading heading
)); )
);
} }
table.push(React.DOM.thead(null, React.DOM.tr(null, row))); table.push(
React.DOM.thead(null, React.DOM.tr(null, row))
);
// body // body
for (i = 0; i < this.token.cells.length; i++) { for (i = 0; i < this.token.cells.length; i++) {
row = []; row = [];
cells = this.token.cells[i]; cells = this.token.cells[i];
for (j = 0; j < cells.length; j++) { for (j = 0; j < cells.length; j++) {
row.push(React.DOM.td( row.push(
React.DOM.td(
this.token.align[j] this.token.align[j]
? {style: {textAlign: this.token.align[j]}} ? {
style: {
textAlign: this.token.align[j],
},
}
: null, : null,
this.inline.output(cells[j]) this.inline.output(cells[j])
)); )
);
} }
body.push(React.DOM.tr(null, row)); body.push(React.DOM.tr(null, row));
} }
@ -900,8 +964,8 @@ Parser.prototype.tok = function() {
return React.DOM.blockquote(null, body); return React.DOM.blockquote(null, body);
} }
case 'list_start': { case 'list_start': {
var type = this.token.ordered ? 'ol' : 'ul' var type = this.token.ordered ? 'ol' : 'ul',
, body = []; body = [];
while (this.next().type !== 'list_end') { while (this.next().type !== 'list_end') {
body.push(this.tok()); body.push(this.tok());
@ -913,9 +977,11 @@ Parser.prototype.tok = function() {
var body = []; var body = [];
while (this.next().type !== 'list_item_end') { while (this.next().type !== 'list_item_end') {
body.push(this.token.type === 'text' body.push(
this.token.type === 'text'
? this.parseText() ? this.parseText()
: this.tok()); : this.tok()
);
} }
return React.DOM.li(null, body); return React.DOM.li(null, body);
@ -931,17 +997,30 @@ Parser.prototype.tok = function() {
} }
case 'html': { case 'html': {
return !this.token.pre && !this.options.pedantic return !this.token.pre && !this.options.pedantic
? React.DOM.span({dangerouslySetInnerHTML: {__html: this.token.text}}) ? React.DOM.span({
dangerouslySetInnerHTML: {
__html: this.token.text,
},
})
: this.token.text; : this.token.text;
} }
case 'paragraph': { case 'paragraph': {
return this.options.paragraphFn return this.options.paragraphFn
? this.options.paragraphFn.call(null, this.inline.output(this.token.text)) ? this.options.paragraphFn.call(
: React.DOM.p(null, this.inline.output(this.token.text)); null,
this.inline.output(this.token.text)
)
: React.DOM.p(
null,
this.inline.output(this.token.text)
);
} }
case 'text': { case 'text': {
return this.options.paragraphFn return this.options.paragraphFn
? this.options.paragraphFn.call(null, this.parseText()) ? this.options.paragraphFn.call(
null,
this.parseText()
)
: React.DOM.p(null, this.parseText()); : React.DOM.p(null, this.parseText());
} }
} }
@ -976,14 +1055,14 @@ function noop() {}
noop.exec = noop; noop.exec = noop;
function merge(obj) { function merge(obj) {
var i = 1 var i = 1, target, key;
, target
, key;
for (; i < arguments.length; i++) { for (; i < arguments.length; i++) {
target = arguments[i]; target = arguments[i];
for (key in target) { for (key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) { if (
Object.prototype.hasOwnProperty.call(target, key)
) {
obj[key] = target[key]; obj[key] = target[key];
} }
} }
@ -1005,13 +1084,10 @@ function marked(src, opt, callback) {
if (opt) opt = merge({}, marked.defaults, opt); if (opt) opt = merge({}, marked.defaults, opt);
var highlight = opt.highlight var highlight = opt.highlight, tokens, pending, i = 0;
, tokens
, pending
, i = 0;
try { try {
tokens = Lexer.lex(src, opt) tokens = Lexer.lex(src, opt);
} catch (e) { } catch (e) {
return callback(e); return callback(e);
} }
@ -1033,9 +1109,7 @@ function marked(src, opt, callback) {
opt.highlight = highlight; opt.highlight = highlight;
return err return err ? callback(err) : callback(null, out);
? callback(err)
: callback(null, out);
}; };
if (!highlight || highlight.length < 3) { if (!highlight || highlight.length < 3) {
@ -1049,14 +1123,18 @@ function marked(src, opt, callback) {
if (token.type !== 'code') { if (token.type !== 'code') {
return --pending || done(); return --pending || done();
} }
return highlight(token.text, token.lang, function(err, code) { return highlight(
token.text,
token.lang,
function(err, code) {
if (code == null || code === token.text) { if (code == null || code === token.text) {
return --pending || done(); return --pending || done();
} }
token.text = code; token.text = code;
token.escaped = true; token.escaped = true;
--pending || done(); --pending || done();
}); }
);
})(tokens[i]); })(tokens[i]);
} }
@ -1068,8 +1146,10 @@ function marked(src, opt, callback) {
} catch (e) { } catch (e) {
e.message += '\nPlease report this to https://github.com/chjj/marked.'; e.message += '\nPlease report this to https://github.com/chjj/marked.';
if ((opt || marked.defaults).silent) { if ((opt || marked.defaults).silent) {
return [React.DOM.p(null, "An error occurred:"), return [
React.DOM.pre(null, e.message)]; React.DOM.p(null, 'An error occurred:'),
React.DOM.pre(null, e.message),
];
} }
throw e; throw e;
} }
@ -1079,11 +1159,10 @@ function marked(src, opt, callback) {
* Options * Options
*/ */
marked.options = marked.options = (marked.setOptions = function(opt) {
marked.setOptions = function(opt) {
merge(marked.defaults, opt); merge(marked.defaults, opt);
return marked; return marked;
}; });
marked.defaults = { marked.defaults = {
gfm: true, gfm: true,
@ -1096,7 +1175,7 @@ marked.defaults = {
highlight: null, highlight: null,
langPrefix: 'lang-', langPrefix: 'lang-',
smartypants: false, smartypants: false,
paragraphFn: null paragraphFn: null,
}; };
/** /**
@ -1116,10 +1195,13 @@ marked.parse = marked;
var Marked = React.createClass({ var Marked = React.createClass({
render: function() { render: function() {
return this.props.children ? return this.props.children
React.DOM.div(null, marked(this.props.children, this.props)) : ? React.DOM.div(
null; null,
} marked(this.props.children, this.props)
)
: null;
},
}); });
module.exports = Marked; module.exports = Marked;

Просмотреть файл

@ -14,12 +14,14 @@ var React = require('React');
var _ = { var _ = {
util: { util: {
type: function (o) { type: function(o) {
return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1]; return Object.prototype.toString
.call(o)
.match(/\[object (\w+)\]/)[1];
}, },
// Deep clone a language definition (e.g. to extend it) // Deep clone a language definition (e.g. to extend it)
clone: function (o) { clone: function(o) {
var type = _.util.type(o); var type = _.util.type(o);
switch (type) { switch (type) {
@ -39,11 +41,11 @@ var _ = {
} }
return o; return o;
} },
}, },
languages: { languages: {
extend: function (id, redef) { extend: function(id, redef) {
var lang = _.util.clone(_.languages[id]); var lang = _.util.clone(_.languages[id]);
for (var key in redef) { for (var key in redef) {
@ -54,19 +56,15 @@ var _ = {
}, },
// Insert a token before another token in a language literal // Insert a token before another token in a language literal
insertBefore: function (inside, before, insert, root) { insertBefore: function(inside, before, insert, root) {
root = root || _.languages; root = root || _.languages;
var grammar = root[inside]; var grammar = root[inside];
var ret = {}; var ret = {};
for (var token in grammar) { for (var token in grammar) {
if (grammar.hasOwnProperty(token)) { if (grammar.hasOwnProperty(token)) {
if (token == before) { if (token == before) {
for (var newToken in insert) { for (var newToken in insert) {
if (insert.hasOwnProperty(newToken)) { if (insert.hasOwnProperty(newToken)) {
ret[newToken] = insert[newToken]; ret[newToken] = insert[newToken];
} }
@ -77,7 +75,7 @@ var _ = {
} }
} }
return root[inside] = ret; return (root[inside] = ret);
}, },
// Traverse a language definition with Depth First Search // Traverse a language definition with Depth First Search
@ -89,7 +87,7 @@ var _ = {
_.languages.DFS(o[i], callback); _.languages.DFS(o[i], callback);
} }
} }
} },
}, },
tokenize: function(text, grammar) { tokenize: function(text, grammar) {
@ -108,7 +106,9 @@ var _ = {
} }
tokenloop: for (var token in grammar) { tokenloop: for (var token in grammar) {
if(!grammar.hasOwnProperty(token) || !grammar[token]) { if (
!grammar.hasOwnProperty(token) || !grammar[token]
) {
continue; continue;
} }
@ -119,7 +119,8 @@ var _ = {
pattern = pattern.pattern || pattern; pattern = pattern.pattern || pattern;
for (var i=0; i<strarr.length; i++) { // Dont cache length as it changes during the loop for (var i = 0; i < strarr.length; i++) {
// Dont cache length as it changes during the loop
var str = strarr[i]; var str = strarr[i];
@ -134,10 +135,11 @@ var _ = {
pattern.lastIndex = 0; pattern.lastIndex = 0;
if (pattern.exec) {
var match = pattern.exec(str); var match = pattern.exec(str);
if (match) { if (match) {
if(lookbehind) { if (lookbehind) {
lookbehindLength = match[1].length; lookbehindLength = match[1].length;
} }
@ -154,7 +156,10 @@ var _ = {
args.push(before); args.push(before);
} }
var wrapped = new Token(token, inside? _.tokenize(match, inside) : match); var wrapped = new Token(
token,
inside ? _.tokenize(match, inside) : match
);
args.push(wrapped); args.push(wrapped);
@ -166,6 +171,7 @@ var _ = {
} }
} }
} }
}
return strarr; return strarr;
}, },
@ -173,7 +179,7 @@ var _ = {
hooks: { hooks: {
all: {}, all: {},
add: function (name, callback) { add: function(name, callback) {
var hooks = _.hooks.all; var hooks = _.hooks.all;
hooks[name] = hooks[name] || []; hooks[name] = hooks[name] || [];
@ -181,24 +187,28 @@ var _ = {
hooks[name].push(callback); hooks[name].push(callback);
}, },
run: function (name, env) { run: function(name, env) {
var callbacks = _.hooks.all[name]; var callbacks = _.hooks.all[name];
if (!callbacks || !callbacks.length) { if (!callbacks || !callbacks.length) {
return; return;
} }
for (var i=0, callback; callback = callbacks[i++];) { for (
var i = 0, callback;
(callback = callbacks[i++]);
) {
callback(env); callback(env);
} }
} },
} },
}; };
var Token = _.Token = function(type, content) { var Token = (_.Token = function(type, content) {
this.type = type; this.type = type;
this.content = content; this.content = content;
}; });
Token.reactify = function(o, key) { Token.reactify = function(o, key) {
if (typeof o == 'string') { if (typeof o == 'string') {
@ -213,120 +223,124 @@ Token.reactify = function(o, key) {
var attributes = { var attributes = {
className: 'token ' + o.type, className: 'token ' + o.type,
key: key key: key,
}; };
if (o.type == 'comment') { if (o.type == 'comment') {
attributes.spellCheck = true; attributes.spellCheck = true;
} }
return React.DOM.span(attributes, Token.reactify(o.content)); return React.DOM.span(
attributes,
Token.reactify(o.content)
);
}; };
_.languages.markup = { _.languages.markup = {
'comment': /&lt;!--[\w\W]*?-->/g, comment: /&lt;!--[\w\W]*?-->/g,
'prolog': /&lt;\?.+?\?>/, prolog: /&lt;\?.+?\?>/,
'doctype': /&lt;!DOCTYPE.+?>/, doctype: /&lt;!DOCTYPE.+?>/,
'cdata': /&lt;!\[CDATA\[[\w\W]*?]]>/i, cdata: /&lt;!\[CDATA\[[\w\W]*?]]>/i,
'tag': { tag: {
pattern: /&lt;\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi, pattern: /&lt;\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,
inside: { inside: {
'tag': { tag: {
pattern: /^&lt;\/?[\w:-]+/i, pattern: /^&lt;\/?[\w:-]+/i,
inside: { inside: {
'punctuation': /^&lt;\/?/, punctuation: /^&lt;\/?/,
'namespace': /^[\w-]+?:/ namespace: /^[\w-]+?:/,
} },
}, },
'attr-value': { 'attr-value': {
pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi, pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,
inside: { inside: {
'punctuation': /=|>|"/g punctuation: /=|>|"/g,
}
}, },
'punctuation': /\/?>/g, },
punctuation: /\/?>/g,
'attr-name': { 'attr-name': {
pattern: /[\w:-]+/g, pattern: /[\w:-]+/g,
inside: { inside: {
'namespace': /^[\w-]+?:/ namespace: /^[\w-]+?:/,
}
}
}
}, },
'entity': /&amp;#?[\da-z]{1,8};/gi },
},
},
entity: /&amp;#?[\da-z]{1,8};/gi,
}; };
_.languages.xml = _.languages.markup;
_.languages.css = { _.languages.css = {
'comment': /\/\*[\w\W]*?\*\//g, comment: /\/\*[\w\W]*?\*\//g,
'atrule': { atrule: {
pattern: /@[\w-]+?.*?(;|(?=\s*{))/gi, pattern: /@[\w-]+?.*?(;|(?=\s*{))/gi,
inside: { inside: {
'punctuation': /[;:]/g punctuation: /[;:]/g,
}
}, },
'url': /url\((["']?).*?\1\)/gi, },
'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/g, url: /url\((["']?).*?\1\)/gi,
'property': /(\b|\B)[\w-]+(?=\s*:)/ig, selector: /[^\{\}\s][^\{\};]*(?=\s*\{)/g,
'string': /("|')(\\?.)*?\1/g, property: /(\b|\B)[\w-]+(?=\s*:)/ig,
'important': /\B!important\b/gi, string: /("|')(\\?.)*?\1/g,
'ignore': /&(lt|gt|amp);/gi, important: /\B!important\b/gi,
'punctuation': /[\{\};:]/g ignore: /&(lt|gt|amp);/gi,
punctuation: /[\{\};:]/g,
}; };
_.languages.insertBefore('markup', 'tag', { _.languages.insertBefore('markup', 'tag', {
'style': { style: {
pattern: /(&lt;|<)style[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/style(>|&gt;)/ig, pattern: /(&lt;|<)style[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/style(>|&gt;)/ig,
inside: { inside: {
'tag': { tag: {
pattern: /(&lt;|<)style[\w\W]*?(>|&gt;)|(&lt;|<)\/style(>|&gt;)/ig, pattern: /(&lt;|<)style[\w\W]*?(>|&gt;)|(&lt;|<)\/style(>|&gt;)/ig,
inside: _.languages.markup.tag.inside inside: _.languages.markup.tag.inside,
},
rest: _.languages.css,
},
}, },
rest: _.languages.css
}
}
}); });
_.languages.clike = { _.languages.clike = {
'comment': { comment: {
pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g, pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,
lookbehind: true lookbehind: true,
}, },
'string': /("|')(\\?.)*?\1/g, string: /("|')(\\?.)*?\1/g,
'class-name': { 'class-name': {
pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig, pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,
lookbehind: true, lookbehind: true,
inside: { inside: {
punctuation: /(\.|\\)/ punctuation: /(\.|\\)/,
}
}, },
'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g, },
'boolean': /\b(true|false)\b/g, keyword: /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,
'function': { boolean: /\b(true|false)\b/g,
function: {
pattern: /[a-z0-9_]+\(/ig, pattern: /[a-z0-9_]+\(/ig,
inside: { inside: {
punctuation: /\(/ punctuation: /\(/,
}
}, },
'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g, },
'operator': /[-+]{1,2}|!|&lt;=?|>=?|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g, number: /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,
'ignore': /&(lt|gt|amp);/gi, operator: /[-+]{1,2}|!|&lt;=?|>=?|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,
'punctuation': /[{}[\];(),.:]/g ignore: /&(lt|gt|amp);/gi,
punctuation: /[{}[\];(),.:]/g,
}; };
_.languages.javascript = _.languages.extend('clike', { _.languages.javascript = _.languages.extend('clike', {
'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, function: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,
'operator': /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/ operator: /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/,
}); });
_.languages.insertBefore('javascript', 'keyword', { _.languages.insertBefore('javascript', 'keyword', {
'regex': { regex: {
pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
lookbehind: true, lookbehind: true,
greedy: true greedy: true,
} },
}); });
_.languages.insertBefore('javascript', 'string', { _.languages.insertBefore('javascript', 'string', {
@ -334,51 +348,208 @@ _.languages.insertBefore('javascript', 'string', {
pattern: /`(?:\\\\|\\?[^\\])*?`/, pattern: /`(?:\\\\|\\?[^\\])*?`/,
greedy: true, greedy: true,
inside: { inside: {
'interpolation': { interpolation: {
pattern: /\$\{[^}]+\}/, pattern: /\$\{[^}]+\}/,
inside: { inside: {
'interpolation-punctuation': { 'interpolation-punctuation': {
pattern: /^\$\{|\}$/, pattern: /^\$\{|\}$/,
alias: 'punctuation' alias: 'punctuation',
},
rest: _.languages.javascript,
},
},
string: /[\s\S]+/,
}, },
rest: _.languages.javascript
}
}, },
'string': /[\s\S]+/
}
}
}); });
_.languages.insertBefore('markup', 'tag', { _.languages.insertBefore('markup', 'tag', {
'script': { script: {
pattern: /(&lt;|<)script[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/script(>|&gt;)/ig, pattern: /(&lt;|<)script[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/script(>|&gt;)/ig,
inside: { inside: {
'tag': { tag: {
pattern: /(&lt;|<)script[\w\W]*?(>|&gt;)|(&lt;|<)\/script(>|&gt;)/ig, pattern: /(&lt;|<)script[\w\W]*?(>|&gt;)|(&lt;|<)\/script(>|&gt;)/ig,
inside: _.languages.markup.tag.inside inside: _.languages.markup.tag.inside,
},
rest: _.languages.javascript,
},
},
});
_.languages.swift = _.languages.extend('clike', {
string: {
pattern: /("|')(\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: true,
inside: {
interpolation: {
pattern: /\\\((?:[^()]|\([^)]+\))+\)/,
inside: {
delimiter: {
pattern: /^\\\(|\)$/,
alias: 'variable',
},
// See rest below
},
},
},
},
keyword: /\b(as|associativity|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|Protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\b/,
number: /\b([\d_]+(\.[\de_]+)?|0x[a-f0-9_]+(\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,
constant: /\b(nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,
atrule: /@\b(IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|noreturn|NS(?:Copying|Managed)|objc|UIApplicationMain|auto_closure)\b/,
builtin: /\b([A-Z]\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\b/,
});
_.languages.swift['string'].inside[
'interpolation'
].inside.rest = _.util.clone(_.languages.swift);
_.languages.c = _.languages.extend('clike', {
keyword: /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
operator: /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,
number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i,
});
_.languages.insertBefore('c', 'string', {
macro: {
// allow for multiline macro definitions
// spaces after the # character compile fine with gcc
pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,
lookbehind: true,
alias: 'property',
inside: {
// highlight the path of the include statement as a string
string: {
pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
lookbehind: true,
},
// highlight macro directives as keywords
directive: {
pattern: /(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
lookbehind: true,
alias: 'keyword',
},
},
},
// highlight predefined macros as constants
constant: /\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/,
});
_.languages.objectivec = _.languages.extend('c', {
keyword: /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while|in|self|super)\b|(@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,
string: /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|@"(\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
operator: /-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/,
});
_.languages.java = _.languages.extend('clike', {
keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
operator: {
pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
lookbehind: true,
},
});
_.languages.insertBefore('java', 'function', {
annotation: {
alias: 'punctuation',
pattern: /(^|[^.])@\w+/,
lookbehind: true,
},
});
_.languages.powershell = {
comment: [
{
pattern: /(^|[^`])<#[\s\S]*?#>/,
lookbehind: true,
},
{
pattern: /(^|[^`])#.*/,
lookbehind: true,
},
],
string: [
{
pattern: /"(`?[\s\S])*?"/,
greedy: true,
inside: {
function: {
pattern: /[^`]\$\(.*?\)/,
// Populated at end of file
inside: {},
},
},
},
{
pattern: /'([^']|'')*'/,
greedy: true,
},
],
// Matches name spaces as well as casts, attribute decorators. Force starting with letter to avoid matching array indices
namespace: /\[[a-z][\s\S]*?\]/i,
boolean: /\$(true|false)\b/i,
variable: /\$\w+\b/i,
// Cmdlets and aliases. Aliases should come last, otherwise "write" gets preferred over "write-host" for example
// Get-Command | ?{ $_.ModuleName -match "Microsoft.PowerShell.(Util|Core|Management)" }
// Get-Alias | ?{ $_.ReferencedCommand.Module.Name -match "Microsoft.PowerShell.(Util|Core|Management)" }
function: [
/\b(Add-(Computer|Content|History|Member|PSSnapin|Type)|Checkpoint-Computer|Clear-(Content|EventLog|History|Item|ItemProperty|Variable)|Compare-Object|Complete-Transaction|Connect-PSSession|ConvertFrom-(Csv|Json|StringData)|Convert-Path|ConvertTo-(Csv|Html|Json|Xml)|Copy-(Item|ItemProperty)|Debug-Process|Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Disconnect-PSSession|Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Enter-PSSession|Exit-PSSession|Export-(Alias|Clixml|Console|Csv|FormatData|ModuleMember|PSSession)|ForEach-Object|Format-(Custom|List|Table|Wide)|Get-(Alias|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Culture|Date|Event|EventLog|EventSubscriber|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job|Location|Member|Module|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|WmiObject)|Group-Object|Import-(Alias|Clixml|Csv|LocalizedData|Module|PSSession)|Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)|Join-Path|Limit-EventLog|Measure-(Command|Object)|Move-(Item|ItemProperty)|New-(Alias|Event|EventLog|Item|ItemProperty|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy)|Out-(Default|File|GridView|Host|Null|Printer|String)|Pop-Location|Push-Location|Read-Host|Receive-(Job|PSSession)|Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)|Remove-(Computer|Event|EventLog|Item|ItemProperty|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)|Rename-(Computer|Item|ItemProperty)|Reset-ComputerMachinePassword|Resolve-Path|Restart-(Computer|Service)|Restore-Computer|Resume-(Job|Service)|Save-Help|Select-(Object|String|Xml)|Send-MailMessage|Set-(Alias|Content|Date|Item|ItemProperty|Location|PSBreakpoint|PSDebug|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)|Show-(Command|ControlPanelItem|EventLog)|Sort-Object|Split-Path|Start-(Job|Process|Service|Sleep|Transaction)|Stop-(Computer|Job|Process|Service)|Suspend-(Job|Service)|Tee-Object|Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)|Trace-Command|Unblock-File|Undo-Transaction|Unregister-(Event|PSSessionConfiguration)|Update-(FormatData|Help|List|TypeData)|Use-Transaction|Wait-(Event|Job|Process)|Where-Object|Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning))\b/i,
/\b(ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i,
],
// per http://technet.microsoft.com/en-us/library/hh847744.aspx
keyword: /\b(Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,
operator: {
pattern: /(\W?)(!|-(eq|ne|gt|ge|lt|le|sh[lr]|not|b?(and|x?or)|(Not)?(Like|Match|Contains|In)|Replace|Join|is(Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,
lookbehind: true,
},
punctuation: /[|{}[\];(),.]/,
};
// Variable interpolation inside strings, and nested expressions
_.languages.powershell.string[
0
].inside.boolean = _.languages.powershell.boolean;
_.languages.powershell.string[
0
].inside.variable = _.languages.powershell.variable;
_.languages.powershell.string[
0
].inside.function.inside = _.util.clone(
_.languages.powershell
);
_.languages.java = _.languages.extend('clike', {
keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
operator: {
pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
lookbehind: true,
}, },
rest: _.languages.javascript
}
}
}); });
var Prism = React.createClass({ var Prism = React.createClass({
statics: { statics: {
_: _ _: _,
}, },
getDefaultProps: function() { getDefaultProps: function() {
return { return {
language: 'javascript' language: 'javascript',
}; };
}, },
render: function() { render: function() {
var grammar = _.languages[this.props.language]; var grammar = _.languages[this.props.language];
if (!grammar) {
grammar = _.languages.javascript;
}
return ( return (
<div className={'prism language-' + this.props.language}> <div
{Token.reactify(_.tokenize(this.props.children, grammar))} className={'prism language-' + this.props.language}
>
{Token.reactify(
_.tokenize(this.props.children, grammar)
)}
</div> </div>
); );
} },
}); });
module.exports = Prism; module.exports = Prism;

Просмотреть файл

@ -18,8 +18,11 @@ var Site = React.createClass({
render: function() { render: function() {
const path = Metadata.config.RN_DEPLOYMENT_PATH; const path = Metadata.config.RN_DEPLOYMENT_PATH;
const version = Metadata.config.RN_VERSION; const version = Metadata.config.RN_VERSION;
const algoliaVersion = version === 'next' ? 'master' : version; const algoliaVersion = version === 'next'
var basePath = '/react-native/' + (path ? path + '/' : ''); ? 'master'
: version;
var basePath = '/react-native/' +
(path ? path + '/' : '');
var currentYear = new Date().getFullYear(); var currentYear = new Date().getFullYear();
var title = this.props.title var title = this.props.title
@ -37,7 +40,10 @@ var Site = React.createClass({
content: 'width=device-width', content: 'width=device-width',
}, },
// Facebook // Facebook
{ property: 'fb:app_id', content: '1677033832619985' }, {
property: 'fb:app_id',
content: '1677033832619985',
},
{ property: 'fb:admins', content: '121800083' }, { property: 'fb:admins', content: '121800083' },
// Open Graph // Open Graph
{ {
@ -51,7 +57,9 @@ var Site = React.createClass({
{ {
property: 'og:url', property: 'og:url',
content: 'https://facebook.github.io/react-native/' + content: 'https://facebook.github.io/react-native/' +
(this.props.path ? this.props.path : 'index.html'), (this.props.path
? this.props.path
: 'index.html'),
}, },
{ {
property: 'og:image', property: 'og:image',
@ -107,7 +115,9 @@ var Site = React.createClass({
<html> <html>
<head> <head>
<title>{title}</title> <title>{title}</title>
{metaTags.map((tag, index) => <meta key={index} {...tag} />)} {metaTags.map((tag, index) => (
<meta key={index} {...tag} />
))}
<base href={basePath} /> <base href={basePath} />
@ -116,8 +126,15 @@ var Site = React.createClass({
href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"
/> />
<link rel="shortcut icon" href="img/favicon.png?2" /> <link
<link rel="stylesheet" href="css/react-native.css" /> rel="shortcut icon"
href="img/favicon.png?2"
/>
<link
rel="stylesheet"
href="css/react-native.css"
/>
<link rel="stylesheet" href="css/prism.css" />
<link <link
rel="alternate" rel="alternate"
@ -131,7 +148,10 @@ var Site = React.createClass({
type="text/css" type="text/css"
/> />
<script type="text/javascript" src="//use.typekit.net/vqa1hcx.js" /> <script
type="text/javascript"
src="//use.typekit.net/vqa1hcx.js"
/>
<script type="text/javascript"> <script type="text/javascript">
{'try{Typekit.load();}catch(e){}'} {'try{Typekit.load();}catch(e){}'}
</script> </script>
@ -154,7 +174,10 @@ var Site = React.createClass({
<img src="img/header_logo.png" /> <img src="img/header_logo.png" />
React Native React Native
</a> </a>
<a className="nav-version" href="/react-native/versions.html"> <a
className="nav-version"
href="/react-native/versions.html"
>
{version} {version}
</a> </a>
<HeaderLinks section={this.props.section} /> <HeaderLinks section={this.props.section} />
@ -165,7 +188,10 @@ var Site = React.createClass({
<footer className="nav-footer"> <footer className="nav-footer">
<section className="sitemap"> <section className="sitemap">
<a href="/react-native" className="nav-home"> <a
href="/react-native"
className="nav-home"
>
<img <img
src="img/header_logo.png" src="img/header_logo.png"
alt="React Native" alt="React Native"
@ -175,46 +201,74 @@ var Site = React.createClass({
</a> </a>
<div> <div>
<h5><a href="docs/">Docs</a></h5> <h5><a href="docs/">Docs</a></h5>
<a href="docs/getting-started.html">Getting Started</a> <a href="docs/getting-started.html">
Getting Started
</a>
<a href="docs/tutorial.html">Tutorial</a> <a href="docs/tutorial.html">Tutorial</a>
<a href="docs/integration-with-existing-apps.html"> <a
href="docs/integration-with-existing-apps.html"
>
Integration With Existing Apps Integration With Existing Apps
</a> </a>
<a href="docs/more-resources.html">More Resources</a> <a href="docs/more-resources.html">
More Resources
</a>
</div> </div>
<div> <div>
<h5><a href="/react-native/support.html">Community</a></h5> <h5>
<a href="/react-native/showcase.html">Showcase</a> <a href="/react-native/support.html">
Community
</a>
</h5>
<a href="/react-native/showcase.html">
Showcase
</a>
<a <a
href="http://www.meetup.com/topics/react-native/" href="http://www.meetup.com/topics/react-native/"
target="_blank"> target="_blank"
>
Upcoming Events Upcoming Events
</a> </a>
<a <a
href="https://www.facebook.com/groups/react.native.community" href="https://www.facebook.com/groups/react.native.community"
target="_blank"> target="_blank"
>
Facebook Group Facebook Group
</a> </a>
<a href="https://twitter.com/reactnative" target="_blank"> <a
href="https://twitter.com/reactnative"
target="_blank"
>
Twitter Twitter
</a> </a>
</div> </div>
<div> <div>
<h5><a href="/react-native/support.html">Help</a></h5> <h5>
<a href="/react-native/support.html">
Help
</a>
</h5>
<a <a
href="http://stackoverflow.com/questions/tagged/react-native" href="http://stackoverflow.com/questions/tagged/react-native"
target="_blank"> target="_blank"
>
Stack Overflow Stack Overflow
</a> </a>
<a href="https://discord.gg/0ZcbPKXt5bZjGY5n"> <a
href="https://discord.gg/0ZcbPKXt5bZjGY5n"
>
Reactiflux Chat Reactiflux Chat
</a> </a>
<a href="/react-native/versions.html" target="_blank"> <a
href="/react-native/versions.html"
target="_blank"
>
Latest Releases Latest Releases
</a> </a>
<a <a
href="https://react-native.canny.io/feature-requests" href="https://react-native.canny.io/feature-requests"
target="_blank"> target="_blank"
>
Feature Requests Feature Requests
</a> </a>
</div> </div>
@ -223,10 +277,14 @@ var Site = React.createClass({
<a href="/react-native/blog">Blog</a> <a href="/react-native/blog">Blog</a>
<a <a
href="https://github.com/facebook/react-native" href="https://github.com/facebook/react-native"
target="_blank"> target="_blank"
>
GitHub GitHub
</a> </a>
<a href="http://facebook.github.io/react/" target="_blank"> <a
href="http://facebook.github.io/react/"
target="_blank"
>
React React
</a> </a>
</div> </div>
@ -240,10 +298,13 @@ var Site = React.createClass({
name="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form"
className="validate" className="validate"
target="_blank" target="_blank"
noValidate> noValidate
>
<div id="mc_embed_signup_scroll"> <div id="mc_embed_signup_scroll">
<label htmlFor="mce-EMAIL"> <label htmlFor="mce-EMAIL">
<h5>Get the React Native Newsletter</h5> <h5>
Get the React Native Newsletter
</h5>
</label> </label>
<input <input
type="email" type="email"
@ -255,8 +316,12 @@ var Site = React.createClass({
required required
/> />
<div <div
style={{ position: 'absolute', left: '-5000px' }} style={{
aria-hidden="true"> position: 'absolute',
left: '-5000px',
}}
aria-hidden="true"
>
<input <input
type="text" type="text"
name="b_db0dd948e2b729ee62625b1a8_47cd41008f" name="b_db0dd948e2b729ee62625b1a8_47cd41008f"
@ -281,7 +346,8 @@ var Site = React.createClass({
<a <a
href="https://code.facebook.com/projects/" href="https://code.facebook.com/projects/"
target="_blank" target="_blank"
className="fbOpenSource"> className="fbOpenSource"
>
<img <img
src="img/oss_logo.png" src="img/oss_logo.png"
alt="Facebook Open Source" alt="Facebook Open Source"
@ -335,7 +401,10 @@ var Site = React.createClass({
__html: "(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';}(jQuery));var $mcj = jQuery.noConflict(true);", __html: "(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';}(jQuery));var $mcj = jQuery.noConflict(true);",
}} }}
/> />
<script type="text/javascript" src="https://snack.expo.io/embed.js" /> <script
type="text/javascript"
src="https://snack.expo.io/embed.js"
/>
</body> </body>
</html> </html>
); );

Просмотреть файл

@ -0,0 +1,139 @@
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+git+java+json+objectivec+powershell+jsx+swift */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}