From 053f384cfea82f1a81e0c35d857ed6cc181bdce2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9ctor=20Ramos?=
<165856+hramos@users.noreply.github.com>
Date: Wed, 4 Oct 2017 09:10:33 -0700
Subject: [PATCH] Add web player files (#112)
---
lib/core/SnackPlayer.js | 140 +++++++++++++++++++++++++++++++++++++
lib/core/WebPlayer.js | 77 ++++++++++++++++++++
lib/static/js/webplayer.js | 75 ++++++++++++++++++++
3 files changed, 292 insertions(+)
create mode 100644 lib/core/SnackPlayer.js
create mode 100644 lib/core/WebPlayer.js
create mode 100644 lib/static/js/webplayer.js
diff --git a/lib/core/SnackPlayer.js b/lib/core/SnackPlayer.js
new file mode 100644
index 0000000000..7e287a3e80
--- /dev/null
+++ b/lib/core/SnackPlayer.js
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @providesModule SnackPlayer
+ */
+'use strict';
+
+var Prism = require('./Prism');
+var React = require('React');
+
+const PropTypes = require('prop-types');
+
+const LatestSDKVersion = '21.0.0';
+var ReactNativeToExpoSDKVersionMap = {
+ '0.48': '21.0.0',
+ '0.47': '20.0.0',
+ '0.46': '19.0.0',
+ '0.45': '18.0.0',
+ '0.44': '17.0.0',
+ '0.43': '16.0.0',
+ '0.42': '15.0.0',
+ '0.41': '14.0.0',
+};
+
+/**
+ * Use the SnackPlayer by including a ```SnackPlayer``` block in markdown.
+ *
+ * Optionally, include url parameters directly after the block's language.
+ * Valid options are name, description, and platform.
+ *
+ * E.g.
+ * ```SnackPlayer?platform=android&name=Hello%20world!
+ * import React from 'react';
+ * import { Text } from 'react-native';
+ *
+ * export default class App extends React.Component {
+ * render() {
+ * return Hello World!;
+ * }
+ * }
+ * ```
+ */
+class SnackPlayer extends React.Component {
+ constructor(props, context) {
+ super(props, context);
+
+ this.parseParams = this.parseParams.bind(this);
+ }
+
+ componentDidMount() {
+ window.ExpoSnack && window.ExpoSnack.initialize();
+ }
+
+ render() {
+ var code = encodeURIComponent(this.props.children);
+ var params = this.parseParams(this.props.params);
+ var platform = params.platform
+ ? params.platform
+ : 'ios';
+ var name = params.name
+ ? decodeURIComponent(params.name)
+ : 'Example';
+ var description = params.description
+ ? decodeURIComponent(params.description)
+ : 'Example usage';
+
+ var optionalProps = {};
+ var { version } = this.context;
+ if (version === 'next') {
+ optionalProps[
+ 'data-snack-sdk-version'
+ ] = LatestSDKVersion;
+ } else {
+ optionalProps[
+ 'data-snack-sdk-version'
+ ] = ReactNativeToExpoSDKVersionMap[version] ||
+ LatestSDKVersion;
+ }
+
+ return (
+
+
+
+ {this.props.children}
+
+
+
+
+
+ );
+ }
+
+ parseParams(paramString) {
+ var params = {};
+
+ if (paramString) {
+ var pairs = paramString.split('&');
+ for (var i = 0; i < pairs.length; i++) {
+ var pair = pairs[i].split('=');
+ params[pair[0]] = pair[1];
+ }
+ }
+
+ return params;
+ }
+}
+
+SnackPlayer.contextTypes = {
+ version: PropTypes.number.isRequired,
+};
+
+module.exports = SnackPlayer;
\ No newline at end of file
diff --git a/lib/core/WebPlayer.js b/lib/core/WebPlayer.js
new file mode 100644
index 0000000000..5bb8305d89
--- /dev/null
+++ b/lib/core/WebPlayer.js
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @providesModule WebPlayer
+ */
+'use strict';
+
+var Prism = require('./Prism');
+var React = require('React');
+
+var WEB_PLAYER_VERSION = '1.10.0';
+
+/**
+ * Use the WebPlayer by including a ```ReactNativeWebPlayer``` block in markdown.
+ *
+ * Optionally, include url parameters directly after the block's language. For
+ * the complete list of url parameters, see: https://github.com/dabbott/react-native-web-player
+ *
+ * E.g.
+ * ```ReactNativeWebPlayer?platform=android
+ * import React from 'react';
+ * import { AppRegistry, Text } from 'react-native';
+ *
+ * const App = () => Hello World!;
+ *
+ * AppRegistry.registerComponent('MyApp', () => App);
+ * ```
+ */
+class WebPlayer extends React.Component {
+ constructor(props, context) {
+ super(props, context);
+
+ this.parseParams = this.parseParams.bind(this);
+ }
+
+ parseParams(paramString) {
+ var params = {};
+
+ if (paramString) {
+ var pairs = paramString.split('&');
+ for (var i = 0; i < pairs.length; i++) {
+ var pair = pairs[i].split('=');
+ params[pair[0]] = pair[1];
+ }
+ }
+
+ return params;
+ }
+
+ render() {
+ var hash = `#code=${encodeURIComponent(this.props.children)}`;
+
+ if (this.props.params) {
+ hash += `&${this.props.params}`;
+ }
+
+ return (
+
+
{this.props.children}
+
+
+ );
+ }
+}
+
+module.exports = WebPlayer;
diff --git a/lib/static/js/webplayer.js b/lib/static/js/webplayer.js
new file mode 100644
index 0000000000..b61ff235b0
--- /dev/null
+++ b/lib/static/js/webplayer.js
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/* eslint-disable module-strict */
+
+(function() {
+ "use strict";
+ // Not on browser
+ if (typeof document === "undefined") {
+ return;
+ }
+
+ document.addEventListener("DOMContentLoaded", init);
+
+ function init() {
+ var mobile = isMobile();
+
+ if (mobile) {
+ document
+ .querySelector(".nav-site-wrapper a[data-target]")
+ .addEventListener("click", toggleTarget);
+ }
+
+ var webPlayerList = document.querySelectorAll(".web-player");
+ // Either show interactive or static code block, depending on desktop or mobile
+ for (var i = 0; i < webPlayerList.length; ++i) {
+ webPlayerList[i].classList.add(mobile ? "mobile" : "desktop");
+
+ if (!mobile) {
+ // Determine location to look up required assets
+ var assetRoot = encodeURIComponent(
+ document.location.origin + "/react-native"
+ );
+
+ // Set iframe src. Do this dynamically so the iframe never loads on mobile.
+ var iframe = webPlayerList[i].querySelector("iframe");
+ iframe.src =
+ iframe.getAttribute("data-src") + "&assetRoot=" + assetRoot;
+ }
+ }
+
+ var snackPlayerList = document.querySelectorAll(".snack-player");
+
+ // Either show interactive or static code block, depending on desktop or mobile
+ for (var i = 0; i < snackPlayerList.length; ++i) {
+ var snackPlayer = snackPlayerList[i];
+ var snackDesktopPlayer = snackPlayer.querySelectorAll(
+ ".desktop-friendly-snack"
+ )[0];
+ var plainCodeExample = snackPlayer.querySelectorAll(
+ ".mobile-friendly-snack"
+ )[0];
+
+ if (mobile) {
+ snackDesktopPlayer.remove();
+ plainCodeExample.style.display = "block";
+ } else {
+ plainCodeExample.remove();
+ }
+ }
+ }
+
+ // Primitive mobile detection
+ function isMobile() {
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
+ navigator.userAgent
+ );
+ }
+})();