├── tests ├── __init__.py ├── REQUIREMENTS.txt ├── routing.py ├── consumers.py ├── test_consumers.py └── settings.py ├── example ├── myapp │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── admin.py │ ├── apps.py │ ├── templates │ │ ├── myapp │ │ │ └── index.html │ │ └── registration │ │ │ └── login.html │ └── static │ │ └── myapp │ │ └── js │ │ ├── constants.js │ │ ├── actions.js │ │ ├── components │ │ ├── Header.react.js │ │ └── Counter.react.js │ │ ├── reducers.js │ │ ├── apps │ │ └── index.react.js │ │ └── containers │ │ └── Root.react.js ├── myproject │ ├── __init__.py │ ├── asgi.py │ ├── routing.py │ ├── wsgi.py │ ├── consumers.py │ ├── urls.py │ └── settings.py ├── REQUIREMENTS.txt ├── .babelrc ├── .eslintrc.js ├── README.rst ├── manage.py └── package.json ├── node ├── docs │ ├── image │ │ ├── github.png │ │ ├── search.png │ │ ├── esdoc-logo-mini.png │ │ ├── esdoc-logo-mini-black.png │ │ ├── badge.svg │ │ └── manual-badge.svg │ ├── coverage.json │ ├── script │ │ ├── patch-for-local.js │ │ ├── manual.js │ │ ├── pretty-print.js │ │ ├── inherited-summary.js │ │ ├── inner-link.js │ │ ├── test-summary.js │ │ ├── search.js │ │ ├── prettify │ │ │ ├── Apache-License-2.0.txt │ │ │ └── prettify.js │ │ └── search_index.js │ ├── badge.svg │ ├── css │ │ ├── prettify-tomorrow.css │ │ └── style.css │ ├── identifiers.html │ ├── source.html │ ├── index.html │ ├── file │ │ └── src │ │ │ └── index.js.html │ ├── variable │ │ └── index.html │ └── dump.json ├── .npmignore ├── .eslintrc.js ├── src │ └── index.js ├── esdoc.json ├── README.md ├── package.json ├── LICENSE └── tests │ └── reduxbridge.test.js ├── MANIFEST.in ├── Makefile ├── .bumpversion.cfg ├── setup.cfg ├── django_redux ├── __init__.py ├── engine.py └── consumers.py ├── .travis.yml ├── .editorconfig ├── setup.py ├── LICENSE ├── .gitignore ├── README.rst └── CODE_OF_CONDUCT.md /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/myapp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/myproject/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/myapp/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/myapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /example/myapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /node/docs/image/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/channels-frontend/django_redux/HEAD/node/docs/image/github.png -------------------------------------------------------------------------------- /node/docs/image/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/channels-frontend/django_redux/HEAD/node/docs/image/search.png -------------------------------------------------------------------------------- /node/.npmignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules 3 | .*.swp 4 | .lock-* 5 | build 6 | .babelrc 7 | webpack.* 8 | /src/ 9 | -------------------------------------------------------------------------------- /example/myapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MyappConfig(AppConfig): 5 | name = 'myapp' 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | recursive-include django_redux/static * 3 | prune django_redux/static/django_redux/node_modules 4 | -------------------------------------------------------------------------------- /node/docs/image/esdoc-logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/channels-frontend/django_redux/HEAD/node/docs/image/esdoc-logo-mini.png -------------------------------------------------------------------------------- /node/docs/image/esdoc-logo-mini-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/channels-frontend/django_redux/HEAD/node/docs/image/esdoc-logo-mini-black.png -------------------------------------------------------------------------------- /tests/REQUIREMENTS.txt: -------------------------------------------------------------------------------- 1 | channels>=2,<3 2 | pytest>=5.4.0 3 | pytest-django 4 | pytest-asyncio 5 | channelsmultiplexer 6 | channels-redis 7 | attrs>=19.2.0 8 | -------------------------------------------------------------------------------- /example/REQUIREMENTS.txt: -------------------------------------------------------------------------------- 1 | asgi-redis==1.0.0 2 | channels==0.17.3 3 | channels-redis==2.4.0 4 | Django==1.11.29 5 | django-webpack-loader==0.4.1 6 | django_redux 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | release: 2 | rm -rf dist 3 | python setup.py sdist bdist_wheel 4 | twine upload dist/* 5 | cd node && npm publish 6 | 7 | update_docs: 8 | cd node && npm run docs 9 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 1.0.0 3 | files = setup.py django_redux/__init__.py node/package.json node/docs/package.json 4 | commit = True 5 | tag = True 6 | 7 | -------------------------------------------------------------------------------- /node/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "airbnb", 3 | "plugins": [ 4 | "react" 5 | ], 6 | env: { 7 | jest: true 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /example/myproject/asgi.py: -------------------------------------------------------------------------------- 1 | import os 2 | import channels.asgi 3 | 4 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") 5 | channel_layer = channels.asgi.get_channel_layer() 6 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | 4 | [aliases] 5 | test=pytest 6 | 7 | [tool:pytest] 8 | DJANGO_SETTINGS_MODULE = tests.settings 9 | python_files = tests.py test_*.py *_tests.py 10 | -------------------------------------------------------------------------------- /django_redux/__init__.py: -------------------------------------------------------------------------------- 1 | _version = "1.0.0" 2 | __version__ = VERSION = tuple(map(int, _version.split('.'))) 3 | 4 | from .engine import action, send_action # noqa 5 | from .consumers import AsyncReduxConsumer # noqa 6 | -------------------------------------------------------------------------------- /example/myapp/templates/myapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0", 5 | "react" 6 | ], 7 | "plugins": [ 8 | "transform-inline-environment-variables", 9 | "transform-object-assign", 10 | "transform-runtime" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/constants.js: -------------------------------------------------------------------------------- 1 | import keyMirror from 'keymirror'; 2 | 3 | const ActionTypes = keyMirror({ 4 | SET_USER: null, 5 | INCREMENT_COUNTER: null, 6 | INCREMENTED_COUNTER: null 7 | }); 8 | 9 | export default ActionTypes; 10 | -------------------------------------------------------------------------------- /node/docs/coverage.json: -------------------------------------------------------------------------------- 1 | { 2 | "coverage": "100%", 3 | "expectCount": 1, 4 | "actualCount": 1, 5 | "files": { 6 | "src/index.js": { 7 | "expectCount": 1, 8 | "actualCount": 1, 9 | "undocumentLines": [] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /node/docs/script/patch-for-local.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (location.protocol === 'file:') { 3 | var elms = document.querySelectorAll('a[href="./"]'); 4 | for (var i = 0; i < elms.length; i++) { 5 | elms[i].href = './index.html'; 6 | } 7 | } 8 | })(); 9 | -------------------------------------------------------------------------------- /node/src/index.js: -------------------------------------------------------------------------------- 1 | export function eventToAction(store) { 2 | 3 | return (event) => { 4 | const action = { ...event.data }; 5 | if (event.origin) { 6 | action.meta = { 7 | ...action.meta, 8 | stream: event.origin, 9 | } 10 | } 11 | return store.dispatch(action); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/myapp/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
{% csrf_token %} 6 | {{ form }} 7 | 8 | 9 |
10 | 11 | -------------------------------------------------------------------------------- /tests/routing.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from channels.routing import ProtocolTypeRouter, URLRouter 3 | from channels.auth import AuthMiddlewareStack 4 | 5 | from .consumers import MyConsumer 6 | 7 | application = ProtocolTypeRouter({ 8 | "websocket": AuthMiddlewareStack( 9 | URLRouter([ 10 | url(r"^ws/$", MyConsumer), 11 | ]) 12 | ), 13 | 14 | }) 15 | -------------------------------------------------------------------------------- /example/myproject/routing.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from channels.routing import ProtocolTypeRouter, URLRouter 3 | from channels.auth import AuthMiddlewareStack 4 | 5 | from .consumers import MyConsumer 6 | 7 | application = ProtocolTypeRouter({ 8 | "websocket": AuthMiddlewareStack( 9 | URLRouter([ 10 | url(r"^ws/$", MyConsumer), 11 | ]) 12 | ), 13 | 14 | }) 15 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/actions.js: -------------------------------------------------------------------------------- 1 | import { createAction } from 'redux-actions'; 2 | 3 | import ActionTypes from './constants'; 4 | import { reduxBridge } from './apps/index.react'; 5 | 6 | 7 | export const incrementCounter = createAction(ActionTypes.INCREMENT_COUNTER, (incrementBy) => { 8 | reduxBridge.send({ 9 | type: ActionTypes.INCREMENT_COUNTER, 10 | payload: incrementBy 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/components/Header.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const Header = function Header(props) { 5 | const username = props.currentUser ? props.currentUser.username : 'Anonymous'; 6 | return (
Hello, {username}!
); 7 | } 8 | 9 | 10 | Header.propTypes = { 11 | currentUser: PropTypes.object 12 | }; 13 | 14 | export default Header; 15 | -------------------------------------------------------------------------------- /node/docs/script/manual.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | var matched = location.pathname.match(/\/(manual\/.*?\/.*\.html)$/); 3 | if (!matched) return; 4 | 5 | var currentName = matched[1]; 6 | var cssClass = '.navigation .manual-toc li[data-link="' + currentName + '"]'; 7 | var styleText = cssClass + '{ display: block; }\n'; 8 | var style = document.createElement('style'); 9 | style.textContent = styleText; 10 | document.querySelector('head').appendChild(style); 11 | })(); 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | services: 4 | - redis-server 5 | branches: 6 | only: 7 | - master 8 | python: 9 | - 3.6 10 | - 3.7 11 | - "pypy3" 12 | env: 13 | - DJANGO="Django>=2,<3" 14 | install: 15 | - pip install -q -U pip 16 | - pip install -q -r tests/REQUIREMENTS.txt 17 | - pip install -q $DJANGO 18 | - nvm install 12 19 | script: 20 | - PYTHONPATH=.:example py.test tests/ 21 | - cd node && npm install --progress=false && npm test 22 | -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module", 5 | "ecmaFeatures": { 6 | "jsx": true 7 | } 8 | }, 9 | "plugins": [ 10 | "react", 11 | "import" 12 | ], 13 | "env": { 14 | "browser": true, 15 | "es6": true, 16 | "mocha": true, 17 | }, 18 | "extends": ["eslint:recommended", "plugin:react/recommended"], 19 | }; 20 | -------------------------------------------------------------------------------- /example/myproject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myproject project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /example/README.rst: -------------------------------------------------------------------------------- 1 | Django-Redux Example 2 | ============================= 3 | 4 | Minimalistic example app that uses django-redux to dispatch and responds to React/Redux actions. 5 | 6 | Quickstart 7 | ---------- 8 | 9 | :: 10 | 11 | $ npm install 12 | $ npm install --devOnly 13 | $ npm run compile 14 | 15 | $ pip install -r REQUIREMENTS.txt 16 | $ ./manage.py migrate 17 | $ ./manage.py runserver 18 | 19 | Credits 20 | ------- 21 | 22 | Most of this code is adapted from `johnpaulett/channel_chat `_. 23 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/reducers.js: -------------------------------------------------------------------------------- 1 | import ActionTypes from './constants'; 2 | 3 | 4 | const initialState = { 5 | counter: 0 6 | }; 7 | 8 | 9 | function reducer(state = initialState, action) { 10 | switch (action.type) { 11 | case ActionTypes.INCREMENTED_COUNTER: 12 | return Object.assign({}, state, { 13 | counter: state.counter + action.payload 14 | }); 15 | case ActionTypes.SET_USER: 16 | return Object.assign({}, state, { 17 | currentUser: action.user 18 | }); 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | export default reducer; 25 | -------------------------------------------------------------------------------- /example/myproject/consumers.py: -------------------------------------------------------------------------------- 1 | from django_redux import action, AsyncReduxConsumer 2 | 3 | 4 | class MyConsumer(AsyncReduxConsumer): 5 | async def connect(self): 6 | await super().connect() 7 | if self.user is not None and self.user.is_authenticated: 8 | await self.send_json({ 9 | 'type': 'SET_USER', 10 | 'user': { 11 | 'username': self.user.username, 12 | } 13 | }) 14 | 15 | @action('INCREMENT_COUNTER') 16 | async def incr_counter(self, message): 17 | await self.broadcast({ 18 | 'type': 'INCREMENTED_COUNTER', 'payload': message['payload'] 19 | }) 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | charset = utf-8 11 | end_of_line = lf 12 | 13 | [*.js] 14 | indent_style = space 15 | indent_size = 2 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | charset = utf-8 19 | end_of_line = lf 20 | 21 | [*.json] 22 | indent_style = space 23 | indent_size = 2 24 | trim_trailing_whitespace = true 25 | insert_final_newline = true 26 | charset = utf-8 27 | end_of_line = lf 28 | 29 | [*.bat] 30 | indent_style = tab 31 | end_of_line = crlf 32 | 33 | [LICENSE] 34 | insert_final_newline = false 35 | 36 | [Makefile] 37 | indent_style = tab 38 | -------------------------------------------------------------------------------- /django_redux/engine.py: -------------------------------------------------------------------------------- 1 | from channels.layers import get_channel_layer 2 | 3 | 4 | async def send_action(group_name, action): 5 | """ 6 | Convenience method to dispatch redux actions from channels. 7 | 8 | Usage:: 9 | 10 | send_action("group_name", { 11 | "type": "MY_ACTION", 12 | "payload": { 13 | "id": 1, 14 | "name": "Lorem", 15 | } 16 | }) 17 | """ 18 | channel_layer = get_channel_layer() 19 | 20 | data = { 21 | 'type': "redux.action", 22 | 'action': action, 23 | } 24 | 25 | await channel_layer.group_send( 26 | group_name, 27 | data 28 | ) 29 | 30 | 31 | def action(action_type): 32 | def wrap(func): 33 | func.action_type = action_type 34 | return func 35 | return wrap 36 | -------------------------------------------------------------------------------- /node/docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | document 13 | document 14 | 100% 15 | 100% 16 | 17 | 18 | -------------------------------------------------------------------------------- /node/docs/image/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | document 13 | document 14 | @ratio@ 15 | @ratio@ 16 | 17 | 18 | -------------------------------------------------------------------------------- /node/docs/image/manual-badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | manual 13 | manual 14 | @value@ 15 | @value@ 16 | 17 | 18 | -------------------------------------------------------------------------------- /node/docs/script/pretty-print.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | prettyPrint(); 3 | var lines = document.querySelectorAll('.prettyprint.linenums li[class^="L"]'); 4 | for (var i = 0; i < lines.length; i++) { 5 | lines[i].id = 'lineNumber' + (i + 1); 6 | } 7 | 8 | var matched = location.hash.match(/errorLines=([\d,]+)/); 9 | if (matched) { 10 | var lines = matched[1].split(','); 11 | for (var i = 0; i < lines.length; i++) { 12 | var id = '#lineNumber' + lines[i]; 13 | var el = document.querySelector(id); 14 | el.classList.add('error-line'); 15 | } 16 | return; 17 | } 18 | 19 | if (location.hash) { 20 | // ``[ ] . ' " @`` are not valid in DOM id. so must escape these. 21 | var id = location.hash.replace(/([\[\].'"@$])/g, '\\$1'); 22 | var line = document.querySelector(id); 23 | if (line) line.classList.add('active'); 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /example/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /node/esdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "./src", 3 | "destination": "./docs", 4 | "plugins": [ 5 | { 6 | "name": "esdoc-standard-plugin", 7 | "option": { 8 | "undocumentIdentifier": {"enable": false}, 9 | "brand": { 10 | "title": "django_redux" 11 | } 12 | } 13 | }, 14 | { 15 | "name": "esdoc-ecmascript-proposal-plugin", 16 | "option": { 17 | "classProperties": true, 18 | "objectRestSpread": true 19 | } 20 | }, 21 | { 22 | "name": "esdoc-importpath-plugin", 23 | "option": { 24 | "replaces": [ 25 | {"from": "^src/", "to": "dist/"}, 26 | {"from": ".js$", "to": ""} 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /node/docs/script/inherited-summary.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function toggle(ev) { 3 | var button = ev.target; 4 | var parent = ev.target.parentElement; 5 | while(parent) { 6 | if (parent.tagName === 'TABLE' && parent.classList.contains('summary')) break; 7 | parent = parent.parentElement; 8 | } 9 | 10 | if (!parent) return; 11 | 12 | var tbody = parent.querySelector('tbody'); 13 | if (button.classList.contains('opened')) { 14 | button.classList.remove('opened'); 15 | button.classList.add('closed'); 16 | tbody.style.display = 'none'; 17 | } else { 18 | button.classList.remove('closed'); 19 | button.classList.add('opened'); 20 | tbody.style.display = 'block'; 21 | } 22 | } 23 | 24 | var buttons = document.querySelectorAll('.inherited-summary thead .toggle'); 25 | for (var i = 0; i < buttons.length; i++) { 26 | buttons[i].addEventListener('click', toggle); 27 | } 28 | })(); 29 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/apps/index.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { render } from 'react-dom'; 4 | import { Provider } from 'react-redux'; 5 | import { createStore, applyMiddleware } from 'redux'; 6 | import thunkMiddleware from 'redux-thunk'; 7 | import { createLogger } from 'redux-logger'; 8 | 9 | import reducer from '../reducers'; 10 | import Root from '../containers/Root.react'; 11 | 12 | import { WebSocketBridge } from 'django-channels'; 13 | import { eventToAction } from 'django_redux'; 14 | 15 | const loggerMiddleware = createLogger(); 16 | 17 | const store = createStore( 18 | reducer, 19 | applyMiddleware( 20 | thunkMiddleware, 21 | loggerMiddleware 22 | ) 23 | ); 24 | 25 | export const reduxBridge = new WebSocketBridge(); 26 | reduxBridge.connect("ws://localhost:8000/ws/"); 27 | reduxBridge.addEventListener("message", eventToAction(store)); 28 | 29 | render( 30 | 31 | 32 | , 33 | document.getElementById('root') 34 | ); 35 | -------------------------------------------------------------------------------- /node/README.md: -------------------------------------------------------------------------------- 1 | ### Usage 2 | 3 | Channels Javascript wrapper for Redux. 4 | 5 | To process messages: 6 | 7 | ``` 8 | import { ReduxBridge } from 'django_redux'; 9 | import { store } from './mystore'; 10 | 11 | const reduxBridge = new ReduxBridge(); 12 | reduxBridge.connect(); 13 | reduxBridge.listen(store); 14 | ``` 15 | 16 | To send messages: 17 | 18 | ``` 19 | reduxBridge.send({prop1: 'value1', prop2: 'value1'}); 20 | 21 | ``` 22 | 23 | To demultiplex specific streams: 24 | 25 | ``` 26 | const reduxBridge = new ReduxBridge(); 27 | reduxBridge.connect(); 28 | reduxBridge.listen(store); 29 | reduxBridge.demultiplex('mystream', function(store, action, stream) { 30 | console.log(action, stream); 31 | store.dispatch(action); 32 | }); 33 | reduxBridge.demultiplex('myotherstream', function(store, action, stream) { 34 | console.info(action, stream); 35 | store.dispatch(action); 36 | }); 37 | ``` 38 | 39 | To send a message to a specific stream: 40 | 41 | ``` 42 | reduxBridge.stream('mystream').send({prop1: 'value1', prop2: 'value1'}) 43 | ``` 44 | -------------------------------------------------------------------------------- /node/docs/script/inner-link.js: -------------------------------------------------------------------------------- 1 | // inner link(#foo) can not correctly scroll, because page has fixed header, 2 | // so, I manually scroll. 3 | (function(){ 4 | var matched = location.hash.match(/errorLines=([\d,]+)/); 5 | if (matched) return; 6 | 7 | function adjust() { 8 | window.scrollBy(0, -55); 9 | var el = document.querySelector('.inner-link-active'); 10 | if (el) el.classList.remove('inner-link-active'); 11 | 12 | // ``[ ] . ' " @`` are not valid in DOM id. so must escape these. 13 | var id = location.hash.replace(/([\[\].'"@$])/g, '\\$1'); 14 | var el = document.querySelector(id); 15 | if (el) el.classList.add('inner-link-active'); 16 | } 17 | 18 | window.addEventListener('hashchange', adjust); 19 | 20 | if (location.hash) { 21 | setTimeout(adjust, 0); 22 | } 23 | })(); 24 | 25 | (function(){ 26 | var els = document.querySelectorAll('[href^="#"]'); 27 | for (var i = 0; i < els.length; i++) { 28 | var el = els[i]; 29 | el.href = location.href + el.getAttribute('href'); // because el.href is absolute path 30 | } 31 | })(); 32 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/containers/Root.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { connect } from 'react-redux'; 5 | import { incrementCounter } from '../actions'; 6 | import Counter from '../components/Counter.react'; 7 | import Header from '../components/Header.react'; 8 | 9 | 10 | const Root = function Root(props) { 11 | return ( 12 |
13 |
14 | 15 |
16 | ); 17 | } 18 | 19 | Root.propTypes = { 20 | currentUser: PropTypes.object, 21 | counter: PropTypes.number, 22 | handleCounterChange: PropTypes.func.isRequired 23 | }; 24 | 25 | 26 | const mapStateToProps = (state) => ({ 27 | counter: state.counter, 28 | currentUser: state.currentUser 29 | }); 30 | 31 | const mapDispatchToProps = (dispatch) => ({ 32 | handleCounterChange: (incrementBy) => { 33 | dispatch(incrementCounter(incrementBy)); 34 | } 35 | }); 36 | 37 | export default connect( 38 | mapStateToProps, 39 | mapDispatchToProps 40 | )(Root); 41 | -------------------------------------------------------------------------------- /example/myproject/urls.py: -------------------------------------------------------------------------------- 1 | """myproject URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf import settings 17 | from django.conf.urls import url, include 18 | from django.conf.urls.static import static 19 | 20 | from django.contrib import admin 21 | from django.views.generic import TemplateView 22 | 23 | 24 | urlpatterns = [ 25 | url(r'^admin/', admin.site.urls), 26 | url(r'^$', TemplateView.as_view(template_name='myapp/index.html'), name='index'), 27 | url('^', include('django.contrib.auth.urls')), 28 | ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 29 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup, find_packages 3 | 4 | VERSION = '1.0.0' 5 | 6 | 7 | f = open(os.path.join(os.path.dirname(__file__), 'README.rst')) 8 | readme = f.read() 9 | f.close() 10 | 11 | setup( 12 | name='django_redux', 13 | version=VERSION, 14 | description='A re-usable bridge between Django channels and Redux Edit', 15 | long_description=readme, 16 | author='Flavio Curella', 17 | author_email='flavio.curella@gmail.com', 18 | url='https://github.com/channels-frontend/django_redux', 19 | include_package_data=True, 20 | packages=find_packages(exclude=['example', 'tests']), 21 | zip_safe=False, 22 | classifiers=[ 23 | 'Development Status :: 4 - Beta', 24 | 'Environment :: Web Environment', 25 | 'Intended Audience :: Developers', 26 | 'Operating System :: OS Independent', 27 | 'Programming Language :: Python :: 2', 28 | 'Programming Language :: Python :: 3', 29 | 'Framework :: Django', 30 | ], 31 | install_requires=[ 32 | "channels", 33 | "Django", 34 | ], 35 | setup_requires=[ 36 | "channels-redis", 37 | "pytest-runner", 38 | "pytest-asyncio", 39 | "pytest-django", 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "", 6 | "babel": { 7 | "presets": [ 8 | "@babel/preset-env" 9 | ], 10 | "plugins": [ 11 | "@babel/plugin-proposal-class-properties" 12 | ] 13 | }, 14 | "scripts": { 15 | "dev": "parcel myapp/templates/myapp/index.html", 16 | "build": "./manage.py collecstatic && parcel build static/myapp/js/apps/index.react.js" 17 | }, 18 | "author": "Flavio Curella", 19 | "license": "MIT", 20 | "dependencies": { 21 | "@babel/runtime": "^7.5.5", 22 | "django-channels": "^2.0.0", 23 | "django_redux": "file:../node", 24 | "keymirror": "^0.1.1", 25 | "prop-types": "^15.7.2", 26 | "react": "^16.9.0", 27 | "react-dom": "^16.9.0", 28 | "react-redux": "^7.1.0", 29 | "redux": "^4.0.4", 30 | "redux-actions": "^2.6.5", 31 | "redux-logger": "^3.0.6", 32 | "redux-thunk": "^2.3.0" 33 | }, 34 | "devDependencies": { 35 | "@babel/core": "^7.5.5", 36 | "@babel/plugin-proposal-class-properties": "^7.5.5", 37 | "@babel/plugin-transform-async-to-generator": "^7.5.0", 38 | "@babel/plugin-transform-runtime": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "parcel-bundler": "^1.12.3" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/myapp/static/myapp/js/components/Counter.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const Counter = ({ counter, handleCounterChange }) => { 5 | let input; 6 | 7 | const handleUserChange = (e) => { 8 | e.preventDefault(); 9 | if (!input.value.trim()) { 10 | return; 11 | } 12 | 13 | handleCounterChange(parseInt(input.value, 10)); 14 | 15 | // clear out the text box 16 | input.value = ''; 17 | }; 18 | 19 | const setInput = (node) => { 20 | input = node; 21 | }; 22 | 23 | 24 | return ( 25 |
26 |
27 |
28 |
29 | 30 | 31 | 32 | 33 |

{counter}

34 |
35 |
36 |
37 |
38 | ); 39 | }; 40 | 41 | 42 | Counter.propTypes = { 43 | handleCounterChange: PropTypes.func.isRequired, 44 | counter: PropTypes.number.isRequired 45 | }; 46 | 47 | export default Counter; 48 | -------------------------------------------------------------------------------- /node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "django_redux", 3 | "version": "1.0.2", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "dev": "parcel src/index.js", 8 | "build": "parcel build src/index.js", 9 | "docs": "rm -rf docs && esdoc -c esdoc.json", 10 | "test": "jest", 11 | "prepare": "npm run build" 12 | }, 13 | "files": [ 14 | "dist/index.js" 15 | ], 16 | "babel": { 17 | "presets": [ 18 | "@babel/preset-env" 19 | ], 20 | "plugins": [ 21 | "@babel/plugin-proposal-class-properties" 22 | ] 23 | }, 24 | "author": "Flavio Curella", 25 | "license": "MIT", 26 | "jest": { 27 | "roots": [ 28 | "tests" 29 | ] 30 | }, 31 | "dependencies": { 32 | "@babel/runtime": "^7.5.5", 33 | "django-channels": "^2.1.0" 34 | }, 35 | "devDependencies": { 36 | "@babel/core": "^7.5.5", 37 | "@babel/plugin-proposal-class-properties": "^7.5.5", 38 | "@babel/plugin-transform-async-to-generator": "^7.5.0", 39 | "@babel/plugin-transform-runtime": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "esdoc": "^1.1.0", 42 | "esdoc-ecmascript-proposal-plugin": "^1.0.0", 43 | "esdoc-importpath-plugin": "^1.0.2", 44 | "esdoc-standard-plugin": "^1.0.0", 45 | "jest": "^24.8.0", 46 | "jest-websocket-mock": "^1.5.0", 47 | "mock-socket": "^8.1.1", 48 | "parcel-bundler": "^1.12.4" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/consumers.py: -------------------------------------------------------------------------------- 1 | from channelsmultiplexer import AsyncJsonWebsocketDemultiplexer 2 | from django_redux import action, AsyncReduxConsumer 3 | 4 | 5 | class MyConsumer(AsyncReduxConsumer): 6 | 7 | async def connect(self): 8 | await super().connect() 9 | if self.user is not None and self.user.is_authenticated: 10 | await self.send_json({ 11 | 'type': 'SET_USER', 12 | 'user': { 13 | 'username': self.user.username, 14 | } 15 | }) 16 | 17 | @action('INCREMENT_COUNTER') 18 | async def incr_counter(self, message, **kwargs): 19 | await self.broadcast({'type': 'INCREMENTED_COUNTER', 'payload': message['payload']}) 20 | 21 | 22 | class MyMultiplexConsumer(AsyncReduxConsumer): 23 | 24 | async def connect(self): 25 | if self.user is not None and self.user.is_authenticated: 26 | await self.send_json({ 27 | 'type': 'SET_USER', 28 | 'user': { 29 | 'username': self.user.username, 30 | } 31 | }) 32 | 33 | @action('INCREMENT_COUNTER') 34 | async def incr_counter(self, message): 35 | await self.broadcast({ 36 | 'type': 'INCREMENTED_COUNTER', 37 | 'payload': message['payload'], 38 | }) 39 | 40 | 41 | class Demultiplexer(AsyncJsonWebsocketDemultiplexer): 42 | 43 | # Wire your JSON consumers here: {stream_name : consumer} 44 | applications = { 45 | "redux": MyMultiplexConsumer, 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Flavio Curella 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of Flavio Curella nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /node/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Flavio Curella 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of Flavio Curella nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask instance folder 57 | instance/ 58 | 59 | # Scrapy stuff: 60 | .scrapy 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ 67 | 68 | # IPython Notebook 69 | .ipynb_checkpoints 70 | 71 | # pyenv 72 | .python-version 73 | 74 | # celery beat schedule file 75 | celerybeat-schedule 76 | 77 | # dotenv 78 | .env 79 | 80 | # virtualenv 81 | .project 82 | venv/ 83 | ENV/ 84 | 85 | 86 | # Spyder project settings 87 | .spyderproject 88 | 89 | node_modules/ 90 | 91 | webpack-stats.json 92 | 93 | # Pycharm 94 | .idea 95 | 96 | # Sqlite3 97 | *.sqlite3 98 | 99 | # Webpack 100 | example/staticfiles/static/webpack_bundles 101 | node/lib 102 | -------------------------------------------------------------------------------- /django_redux/consumers.py: -------------------------------------------------------------------------------- 1 | import inspect 2 | from channels.generic import websocket 3 | 4 | 5 | class AsyncReduxConsumer(websocket.AsyncJsonWebsocketConsumer): 6 | 7 | async def connect(self): 8 | await super().connect() 9 | await self.channel_layer.group_add("broadcast", self.channel_name) 10 | self.user = self.scope.get("user") 11 | 12 | if self.user is not None and self.user.is_authenticated: 13 | await self.channel_layer.group_add(f"user.{self.user.pk}", self.channel_name) 14 | 15 | def _list_actions(self): 16 | methods = inspect.getmembers(self, predicate=inspect.ismethod) 17 | return [m[1] for m in methods if hasattr(m[1], 'action_type')] 18 | 19 | def _get_actions(self, action_type): 20 | methods = inspect.getmembers(self, predicate=inspect.ismethod) 21 | return [m[1] for m in methods if hasattr(m[1], 'action_type') and m[1].action_type == action_type] 22 | 23 | async def receive_json(self, action, **kwargs): 24 | # Simple protection to only expose upper case methods 25 | # to client-side directives 26 | action_type = action['type'].upper() 27 | 28 | methods = self._get_actions(action_type) 29 | 30 | if not methods: 31 | raise NotImplementedError('{} not implemented'.format(action_type)) 32 | 33 | [await method(action) for method in methods] 34 | 35 | async def broadcast(self, action): 36 | data = { 37 | 'type': "redux.action", 38 | 'action': action, 39 | } 40 | await self.channel_layer.group_send("broadcast", data) 41 | 42 | async def redux_action(self, event): 43 | await self.send_json(event["action"]) 44 | -------------------------------------------------------------------------------- /tests/test_consumers.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from channels.testing import WebsocketCommunicator 4 | 5 | from .consumers import MyConsumer, Demultiplexer 6 | from .routing import application 7 | 8 | 9 | def test_consumer_action(): 10 | assert hasattr(MyConsumer.incr_counter, 'action_type') 11 | assert MyConsumer.incr_counter.action_type == 'INCREMENT_COUNTER' 12 | 13 | 14 | @pytest.mark.asyncio 15 | async def test_consumer(): 16 | communicator = WebsocketCommunicator(application, "/ws/") 17 | await communicator.connect() 18 | await communicator.send_json_to({ 19 | 'type': 'INCREMENT_COUNTER', 20 | 'payload': 2, 21 | }) 22 | received = await communicator.receive_json_from() 23 | assert received == { 24 | 'type': 'INCREMENTED_COUNTER', 25 | 'payload': 2, 26 | } 27 | await communicator.disconnect() 28 | 29 | 30 | @pytest.mark.asyncio 31 | async def test_consumer_no_auth(): 32 | communicator = WebsocketCommunicator(MyConsumer, "/") 33 | await communicator.connect() 34 | await communicator.send_json_to({ 35 | 'type': 'INCREMENT_COUNTER', 36 | 'payload': 2, 37 | }) 38 | received = await communicator.receive_json_from() 39 | assert received == { 40 | 'type': 'INCREMENTED_COUNTER', 41 | 'payload': 2, 42 | } 43 | await communicator.disconnect() 44 | 45 | 46 | @pytest.mark.asyncio 47 | async def __test_multiplexer(): 48 | communicator = WebsocketCommunicator(Demultiplexer, "/") 49 | await communicator.connect() 50 | await communicator.send_json_to({ 51 | 'stream': 'redux', 52 | 'payload': { 53 | 'type': 'INCREMENT_COUNTER', 54 | 'payload': 2, 55 | } 56 | }) 57 | 58 | await communicator.disconnect() 59 | -------------------------------------------------------------------------------- /node/docs/script/test-summary.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function toggle(ev) { 3 | var button = ev.target; 4 | var parent = ev.target.parentElement; 5 | while(parent) { 6 | if (parent.tagName === 'TR' && parent.classList.contains('test-describe')) break; 7 | parent = parent.parentElement; 8 | } 9 | 10 | if (!parent) return; 11 | 12 | var direction; 13 | if (button.classList.contains('opened')) { 14 | button.classList.remove('opened'); 15 | button.classList.add('closed'); 16 | direction = 'closed'; 17 | } else { 18 | button.classList.remove('closed'); 19 | button.classList.add('opened'); 20 | direction = 'opened'; 21 | } 22 | 23 | var targetDepth = parseInt(parent.dataset.testDepth, 10) + 1; 24 | var nextElement = parent.nextElementSibling; 25 | while (nextElement) { 26 | var depth = parseInt(nextElement.dataset.testDepth, 10); 27 | if (depth >= targetDepth) { 28 | if (direction === 'opened') { 29 | if (depth === targetDepth) nextElement.style.display = ''; 30 | } else if (direction === 'closed') { 31 | nextElement.style.display = 'none'; 32 | var innerButton = nextElement.querySelector('.toggle'); 33 | if (innerButton && innerButton.classList.contains('opened')) { 34 | innerButton.classList.remove('opened'); 35 | innerButton.classList.add('closed'); 36 | } 37 | } 38 | } else { 39 | break; 40 | } 41 | nextElement = nextElement.nextElementSibling; 42 | } 43 | } 44 | 45 | var buttons = document.querySelectorAll('.test-summary tr.test-describe .toggle'); 46 | for (var i = 0; i < buttons.length; i++) { 47 | buttons[i].addEventListener('click', toggle); 48 | } 49 | 50 | var topDescribes = document.querySelectorAll('.test-summary tr[data-test-depth="0"]'); 51 | for (var i = 0; i < topDescribes.length; i++) { 52 | topDescribes[i].style.display = ''; 53 | } 54 | })(); 55 | -------------------------------------------------------------------------------- /node/docs/css/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /node/docs/identifiers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index | django_redux API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | 23 | 30 |
31 | 32 | 39 | 40 |

References

41 | 42 | 43 | 44 |

Variable Summary

45 | 46 | 47 | 48 | 49 | 56 | 71 | 75 | 76 | 77 |
Static Public Variable Summary
50 | public 51 | 52 | 53 | 54 | 55 | 57 |
58 |

59 | 60 | 61 | reduxBridge: ReduxSocketBridge 62 |

63 |
64 |
65 | 66 | 67 |

Convenience singleton for ReduxSocketBridge.

68 |
69 |
70 |
72 | 73 | 74 |
78 |
79 | 80 | 81 |
82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /node/docs/source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Source | django_redux API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | 23 | 30 |
31 | 32 | 39 | 40 |

Source 1/1

41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
FileIdentifierDocumentSizeLinesUpdated
src/index.jsreduxBridge100 %1/11742 byte622017-04-02 20:41:01 (UTC)
65 |
66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /node/docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | django_redux API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | 23 | 30 |
31 | 32 | 39 | 40 |

Usage

41 |

Channels Javascript wrapper for Redux.

42 |

To process messages:

43 |
import { ReduxBridge } from 'django_redux';
44 | import { store } from './mystore';
45 | 
46 | const reduxBridge = new ReduxBridge();
47 | reduxBridge.connect();
48 | reduxBridge.listen(store);
49 | 

To send messages:

50 |
reduxBridge.send({prop1: 'value1', prop2: 'value1'});
51 | 

To demultiplex specific streams:

52 |
const reduxBridge = new ReduxBridge();
53 | reduxBridge.connect();
54 | reduxBridge.listen(store);
55 | reduxBridge.demultiplex('mystream', function(store, action, stream) {
56 |   console.log(action, stream);
57 |   store.dispatch(action);
58 | });
59 | reduxBridge.demultiplex('myotherstream', function(store, action, stream) {
60 |   console.info(action, stream);
61 |   store.dispatch(action);
62 | });
63 | 

To send a message to a specific stream:

64 |
reduxBridge.stream('mystream').send({prop1: 'value1', prop2: 'value1'})
65 | 
66 |
67 | 68 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Django Redux 2 | ============================= 3 | 4 | A re-usable bridge between Django channels and Redux. 5 | 6 | Quickstart 7 | ---------- 8 | 9 | :: 10 | 11 | $ pip install django_redux 12 | $ npm install django-channels django_redux 13 | 14 | Create a file called `engine.py` for your project:: 15 | 16 | from django_redux import action, AsyncReduxConsumer 17 | 18 | 19 | class MyConsumer(AsyncReduxConsumer): 20 | 21 | async def connect(self, message): 22 | if message.user.is_authenticated: 23 | await self.send_json({ 24 | 'type': 'SET_USER', 25 | 'user': { 26 | 'username': self.message.user.username, 27 | } 28 | }) 29 | 30 | # This method will be called when the `INCREMENT_COUNTER` action gets 31 | # fired from the JS via the reduxBridge (see below). 32 | @action('INCREMENT_COUNTER') 33 | async def incr_counter(self, message): 34 | await self.send_json({'type': 'INCREMENTED_COUNTER', 'incrementBy': message['incrementBy']}) 35 | 36 | 37 | In your js entry point:: 38 | 39 | // app.js 40 | 41 | import React from 'react'; 42 | 43 | import { render } from 'react-dom'; 44 | import { Provider } from 'react-redux'; 45 | import { createStore, } from 'redux'; 46 | 47 | import reducer from '../reducers'; 48 | import Root from '../containers/Root.react'; 49 | 50 | import { WebSocketBridge } from 'django-channels'; 51 | import { eventToAction } from 'django_redux'; 52 | 53 | const store = createStore( 54 | reducer, 55 | ); 56 | 57 | 58 | export const reduxBridge = new WebSocketBridge(); 59 | reduxBridge.connect("ws://localhost:8000/ws/"); 60 | reduxBridge.addEventListener("message", eventToAction(store)); 61 | 62 | render( 63 | 64 | 65 | , 66 | document.getElementById('root') 67 | ); 68 | 69 | To send an action from redux:: 70 | 71 | import { createAction } from 'redux-actions'; 72 | 73 | import ActionTypes from './constants'; 74 | import { reduxBridge } from './app'; 75 | 76 | 77 | export const incrementCounter = createAction(ActionTypes.INCREMENT_COUNTER, (incrementBy) => { 78 | reduxBridge.send({ 79 | type: ActionTypes.INCREMENT_COUNTER, 80 | incrementBy 81 | }); 82 | }); 83 | 84 | To send an action from the backend:: 85 | 86 | from django_redux import send_action 87 | 88 | await send_action('mygroup', { 89 | 'type': 'ACTION_NAME', 90 | 'payload': {'any': 'thing'}, 91 | }) 92 | 93 | Groups 94 | ------ 95 | 96 | All clients are automatically added to a group called `"broadcast"`. 97 | 98 | Authenticated users are automatically added to a group called `"user.{user.pk}"` so you they can be conveniently addressed. 99 | 100 | TODO: 101 | 102 | * Tests 103 | * ``send_action`` 104 | * Data binding 105 | * Docs 106 | * Multiplexing 107 | 108 | Credits 109 | ------- 110 | 111 | Most of this code is adapted from `johnpaulett/channel_chat `_. 112 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at community@curella.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /node/docs/script/search.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | var searchIndex = window.esdocSearchIndex; 3 | var searchBox = document.querySelector('.search-box'); 4 | var input = document.querySelector('.search-input'); 5 | var result = document.querySelector('.search-result'); 6 | var selectedIndex = -1; 7 | var prevText; 8 | 9 | // active search box and focus when mouse enter on search box. 10 | searchBox.addEventListener('mouseenter', function(){ 11 | searchBox.classList.add('active'); 12 | input.focus(); 13 | }); 14 | 15 | // search with text when key is upped. 16 | input.addEventListener('keyup', function(ev){ 17 | var text = ev.target.value.toLowerCase(); 18 | if (!text) { 19 | result.style.display = 'none'; 20 | result.innerHTML = ''; 21 | return; 22 | } 23 | 24 | if (text === prevText) return; 25 | prevText = text; 26 | 27 | var html = {class: [], method: [], member: [], function: [], variable: [], typedef: [], external: [], file: [], test: [], testFile: []}; 28 | var len = searchIndex.length; 29 | var kind; 30 | for (var i = 0; i < len; i++) { 31 | var pair = searchIndex[i]; 32 | if (pair[0].indexOf(text) !== -1) { 33 | kind = pair[3]; 34 | html[kind].push('
  • ' + pair[2] + '
  • '); 35 | } 36 | } 37 | 38 | var innerHTML = ''; 39 | for (kind in html) { 40 | var list = html[kind]; 41 | if (!list.length) continue; 42 | innerHTML += '
  • ' + kind + '
  • \n' + list.join('\n'); 43 | } 44 | result.innerHTML = innerHTML; 45 | if (innerHTML) result.style.display = 'block'; 46 | selectedIndex = -1; 47 | }); 48 | 49 | // down, up and enter key are pressed, select search result. 50 | input.addEventListener('keydown', function(ev){ 51 | if (ev.keyCode === 40) { 52 | // arrow down 53 | var current = result.children[selectedIndex]; 54 | var selected = result.children[selectedIndex + 1]; 55 | if (selected && selected.classList.contains('search-separator')) { 56 | var selected = result.children[selectedIndex + 2]; 57 | selectedIndex++; 58 | } 59 | 60 | if (selected) { 61 | if (current) current.classList.remove('selected'); 62 | selectedIndex++; 63 | selected.classList.add('selected'); 64 | } 65 | } else if (ev.keyCode === 38) { 66 | // arrow up 67 | var current = result.children[selectedIndex]; 68 | var selected = result.children[selectedIndex - 1]; 69 | if (selected && selected.classList.contains('search-separator')) { 70 | var selected = result.children[selectedIndex - 2]; 71 | selectedIndex--; 72 | } 73 | 74 | if (selected) { 75 | if (current) current.classList.remove('selected'); 76 | selectedIndex--; 77 | selected.classList.add('selected'); 78 | } 79 | } else if (ev.keyCode === 13) { 80 | // enter 81 | var current = result.children[selectedIndex]; 82 | if (current) { 83 | var link = current.querySelector('a'); 84 | if (link) location.href = link.href; 85 | } 86 | } else { 87 | return; 88 | } 89 | 90 | ev.preventDefault(); 91 | }); 92 | 93 | // select search result when search result is mouse over. 94 | result.addEventListener('mousemove', function(ev){ 95 | var current = result.children[selectedIndex]; 96 | if (current) current.classList.remove('selected'); 97 | 98 | var li = ev.target; 99 | while (li) { 100 | if (li.nodeName === 'LI') break; 101 | li = li.parentElement; 102 | } 103 | 104 | if (li) { 105 | selectedIndex = Array.prototype.indexOf.call(result.children, li); 106 | li.classList.add('selected'); 107 | } 108 | }); 109 | 110 | // clear search result when body is clicked. 111 | document.body.addEventListener('click', function(ev){ 112 | selectedIndex = -1; 113 | result.style.display = 'none'; 114 | result.innerHTML = ''; 115 | }); 116 | 117 | })(); 118 | -------------------------------------------------------------------------------- /node/docs/file/src/index.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/index.js | django_redux API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | 23 | 30 |
    31 | 32 | 39 | 40 |

    src/index.js

    41 |
    import { WebSocketBridge } from 'django-channels';
     42 | 
     43 | 
     44 | export class ReduxBridge extends WebSocketBridge {
     45 |   /**
     46 |    * Starts listening for messages on the websocket, demultiplexing if necessary.
     47 |    *
     48 |    * @param      {Object}  store         Your redux store.
     49 |    * @param      {Function}  [cb]         Callback to be execute when a message
     50 |    * arrives. The callback will receive `store`, `action` and `stream` parameters.
     51 |    * By default it will call `store.dispatch(action)`;
     52 |    *
     53 |    * @example
     54 |    * const webSocketBridge = new WebSocketBridge();
     55 |    * webSocketBridge.connect();
     56 |    * webSocketBridge.listen(store);
     57 |    */
     58 |   listen(store, cb = this.storeDispatch) {
     59 |     this.default_cb = cb;
     60 |     this.socket.onmessage = (event) => {
     61 |       const msg = JSON.parse(event.data);
     62 |       let action;
     63 |       let stream;
     64 |       if (msg.stream !== undefined) {
     65 |         action = msg.payload;
     66 |         stream = msg.stream;
     67 |         const stream_cb = this.streams[stream];
     68 |         stream_cb ? stream_cb(store, action, stream) : null;
     69 |       } else {
     70 |         action = msg;
     71 |         stream = null;
     72 |         this.default_cb ? this.default_cb(store, action, stream) : null;
     73 |       }
     74 |     };
     75 | 
     76 |     this.socket.onopen = () => {
     77 |       const state = store.getState();
     78 | 
     79 |       if (state.currentUser !== null) {
     80 |         // the connection was dropped. Call the recovery logic
     81 |         this.options.onreconnect(state);
     82 |       }
     83 |     };
     84 |   }
     85 | 
     86 |   storeDispatch(store, action, stream) {
     87 |     return store.dispatch(action);
     88 |   }
     89 | 
     90 | }
     91 | 
     92 | /**
     93 |  * Convenience singleton for `ReduxSocketBridge`.
     94 |  * @example
     95 |  * import { ReduxBridge } from 'django_redux';
     96 |  *
     97 |  * ReduxBridge.connect();
     98 |  * ReduxBridge.listen(store);
     99 |  *
    100 |  * @type       {ReduxSocketBridge}
    101 |  */
    102 | export const reduxBridge = new ReduxBridge();
    103 | 
    104 | 105 |
    106 | 107 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for myproject project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = os.environ.get('SECRET_KEY', 'itsasecret!') 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | 'channels', 42 | 43 | ] 44 | 45 | MIDDLEWARE = [ 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.messages.middleware.MessageMiddleware', 52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 53 | ] 54 | 55 | ROOT_URLCONF = 'myproject.urls' 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'myproject.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | 87 | # Password validation 88 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 89 | 90 | AUTH_PASSWORD_VALIDATORS = [ 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 102 | }, 103 | ] 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | 111 | TIME_ZONE = 'UTC' 112 | 113 | USE_I18N = False 114 | 115 | USE_L10N = False 116 | 117 | USE_TZ = True 118 | 119 | 120 | # Static files (CSS, JavaScript, Images) 121 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 122 | 123 | STATIC_URL = '/static/' 124 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 125 | 126 | STATICFILES_DIRS = [ 127 | os.path.join(BASE_DIR, 'staticfiles', 'static'), 128 | ] 129 | 130 | LOGIN_REDIRECT_URL = '/' 131 | 132 | CHANNEL_LAYERS = { 133 | 'default': { 134 | 'BACKEND': 'channels_redis.core.RedisChannelLayer', 135 | 'CONFIG': { 136 | 'hosts': [('localhost', 6379)], 137 | }, 138 | }, 139 | } 140 | 141 | ASGI_APPLICATION = 'tests.routing.application', 142 | -------------------------------------------------------------------------------- /example/myproject/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for myproject project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = os.environ.get('SECRET_KEY', 'itsasecret!') 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | 'channels', 42 | 'myapp', 43 | ] 44 | 45 | MIDDLEWARE = [ 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.messages.middleware.MessageMiddleware', 52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 53 | ] 54 | 55 | ROOT_URLCONF = 'myproject.urls' 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'myproject.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | 87 | # Password validation 88 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 89 | 90 | AUTH_PASSWORD_VALIDATORS = [ 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 102 | }, 103 | ] 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | 111 | TIME_ZONE = 'UTC' 112 | 113 | USE_I18N = False 114 | 115 | USE_L10N = False 116 | 117 | USE_TZ = True 118 | 119 | 120 | # Static files (CSS, JavaScript, Images) 121 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 122 | 123 | STATIC_URL = '/static/' 124 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 125 | 126 | STATICFILES_DIRS = [ 127 | os.path.join(BASE_DIR, 'staticfiles', 'static'), 128 | ] 129 | 130 | LOGIN_REDIRECT_URL = '/' 131 | 132 | CHANNEL_LAYERS = { 133 | 'default': { 134 | 'BACKEND': 'channels_redis.core.RedisChannelLayer', 135 | 'CONFIG': { 136 | 'hosts': [('localhost', 6379)], 137 | }, 138 | }, 139 | } 140 | 141 | ASGI_APPLICATION = 'myproject.routing.application' 142 | -------------------------------------------------------------------------------- /node/docs/variable/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Variable | django_redux API Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | Home 18 | 19 | Reference 20 | Source 21 | 22 | 23 | 30 |
    31 | 32 | 39 | 40 |

    Variable

    41 |
    42 | 43 | 44 | 45 | 46 | 53 | 68 | 72 | 73 | 74 |
    Static Public Summary
    47 | public 48 | 49 | 50 | 51 | 52 | 54 |
    55 |

    56 | 57 | 58 | reduxBridge: ReduxSocketBridge 59 |

    60 |
    61 |
    62 | 63 | 64 |

    Convenience singleton for ReduxSocketBridge.

    65 |
    66 |
    67 |
    69 | 70 | 71 |
    75 |
    76 |

    Static Public

    77 | 78 |
    79 |

    80 | public 81 | 82 | 83 | 84 | 85 | 86 | reduxBridge: ReduxSocketBridge 87 | 88 | 89 | 90 | source 91 | 92 |

    93 | 94 |
    import {reduxBridge} from 'django_redux/lib/index'
    95 | 96 | 97 |

    Convenience singleton for ReduxSocketBridge.

    98 |
    99 | 100 | 101 | 102 |
    103 |
    104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
    116 |

    Example:

    117 | 118 |
    119 | 120 |
    import { ReduxBridge } from 'django_redux';
    121 | 
    122 | ReduxBridge.connect();
    123 | ReduxBridge.listen(store);
    124 |
    125 |
    126 | 127 | 128 | 129 | 130 | 131 |
    132 |
    133 |
    134 | 135 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /node/tests/reduxbridge.test.js: -------------------------------------------------------------------------------- 1 | import WS from "jest-websocket-mock"; 2 | import { WebSocketBridge } from 'django-channels'; 3 | import { eventToAction } from '../src/'; 4 | 5 | 6 | describe('ReduxBridge', () => { 7 | const URL = 'ws://localhost'; 8 | const websocketOptions = { maxReconnectionDelay: 500, minReconnectionDelay: 50, reconnectionDelayGrowFactor: 1 }; 9 | 10 | afterEach(() => { 11 | WS.clean(); 12 | }); 13 | 14 | test('Processes messages', async () => { 15 | const mockServer = new WS(URL, { jsonProtocol: true }); 16 | const store = { 17 | dispatch: jest.fn(), 18 | }; 19 | const reduxBridge = new WebSocketBridge(); 20 | 21 | reduxBridge.connect(URL, undefined, websocketOptions); 22 | reduxBridge.addEventListener("message", eventToAction(store)); 23 | await mockServer.connected; 24 | 25 | mockServer.send({"type": "test", "payload": "message 1"}); 26 | mockServer.send({"type": "test", "payload": "message 2"}); 27 | 28 | expect(store.dispatch.mock.calls.length).toBe(2); 29 | expect(store.dispatch.mock.calls[0][0]).toEqual({ type: 'test', payload: 'message 1' }); 30 | }); 31 | 32 | test('Ignores multiplexed messages for unregistered streams', async () => { 33 | const mockServer = new WS(URL, { jsonProtocol: true}); 34 | const store = { 35 | dispatch: jest.fn(), 36 | }; 37 | const reduxBridge = new WebSocketBridge(); 38 | 39 | reduxBridge.connect(URL, undefined, websocketOptions); 40 | reduxBridge.addEventListener("message", eventToAction(store)); 41 | await mockServer.connected; 42 | 43 | mockServer.send({"stream": "stream1", "payload": {"type": "test", "payload": "message 1"}}); 44 | expect(store.dispatch.mock.calls.length).toBe(0); 45 | }); 46 | 47 | test('Demultiplexes messages only when they have a stream', async () => { 48 | const mockServer = new WS(URL, { jsonProtocol: true }); 49 | 50 | const store = { 51 | dispatch: jest.fn(), 52 | }; 53 | const reduxBridge = new WebSocketBridge(store); 54 | 55 | const myMock2 = jest.fn(); 56 | const myMock3 = jest.fn(); 57 | 58 | reduxBridge.connect(URL, undefined, websocketOptions); 59 | 60 | await mockServer.connected; 61 | 62 | reduxBridge.addEventListener("message", eventToAction(store)); 63 | reduxBridge.demultiplex('stream1', myMock2); 64 | reduxBridge.demultiplex('stream2', myMock3); 65 | 66 | mockServer.send({"type": "test", "payload": "message 1"}); 67 | expect(store.dispatch.mock.calls.length).toBe(1); 68 | expect(myMock2.mock.calls.length).toBe(0); 69 | expect(myMock3.mock.calls.length).toBe(0); 70 | 71 | mockServer.send({"stream": "stream1", "payload": {"type": "test", "payload": "message 1"}}); 72 | 73 | expect(store.dispatch.mock.calls.length).toBe(1); 74 | expect(myMock2.mock.calls.length).toBe(1); 75 | expect(myMock3.mock.calls.length).toBe(0); 76 | 77 | expect(myMock2.mock.calls[0][0].data).toEqual({ type: 'test', payload: 'message 1' }); 78 | expect(myMock2.mock.calls[0][0].origin).toBe('stream1'); 79 | 80 | mockServer.send({"stream": "stream2", "payload": {"type": "test", "payload": "message 2"}}); 81 | 82 | expect(store.dispatch.mock.calls.length).toBe(1); 83 | expect(myMock2.mock.calls.length).toBe(1); 84 | expect(myMock3.mock.calls.length).toBe(1); 85 | 86 | expect(myMock3.mock.calls[0][0].data).toEqual({ type: 'test', payload: 'message 2' }); 87 | expect(myMock3.mock.calls[0][0].origin).toBe('stream2'); 88 | }); 89 | 90 | test('Demultiplexes messages', async () => { 91 | const mockServer = new WS(URL, { jsonProtocol: true }); 92 | 93 | const store = { 94 | dispatch: jest.fn(), 95 | }; 96 | const store2 = { 97 | dispatch: jest.fn(), 98 | }; 99 | const store3 = { 100 | dispatch: jest.fn(), 101 | }; 102 | const reduxBridge = new WebSocketBridge(); 103 | 104 | const myMock = jest.fn(); 105 | const myMock2 = jest.fn(); 106 | 107 | reduxBridge.connect(URL, undefined, websocketOptions); 108 | 109 | await mockServer.connected; 110 | 111 | reduxBridge.stream('stream1').addEventListener("message", eventToAction(store)); 112 | reduxBridge.stream('stream1').addEventListener("message", eventToAction(store2)); 113 | reduxBridge.demultiplex('stream2', eventToAction(store3)); 114 | 115 | mockServer.send({"type": "test", "payload": "message 1"}); 116 | mockServer.send({"type": "test", "payload": "message 2"}); 117 | 118 | expect(store.dispatch.mock.calls.length).toBe(0); 119 | expect(store2.dispatch.mock.calls.length).toBe(0); 120 | expect(store3.dispatch.mock.calls.length).toBe(0); 121 | 122 | mockServer.send({"stream": "stream1", "payload": {"type": "test", "payload": "message 1"}}); 123 | 124 | expect(store.dispatch.mock.calls.length).toBe(1); 125 | expect(store2.dispatch.mock.calls.length).toBe(1); 126 | expect(store3.dispatch.mock.calls.length).toBe(0); 127 | 128 | expect(store.dispatch.mock.calls[0][0]).toEqual({ type: 'test', payload: 'message 1', meta: {stream: 'stream1'} }); 129 | expect(store2.dispatch.mock.calls[0][0]).toEqual({ type: 'test', payload: 'message 1', meta: {stream: 'stream1'} }); 130 | 131 | mockServer.send({"stream": "stream2", "payload": {"type": "test", "payload": "message 2"}}); 132 | 133 | expect(store.dispatch.mock.calls.length).toBe(1); 134 | expect(store2.dispatch.mock.calls.length).toBe(1); 135 | expect(store3.dispatch.mock.calls.length).toBe(1); 136 | 137 | expect(store3.dispatch.mock.calls[0][0]).toEqual({ type: 'test', payload: 'message 2', meta: {stream: 'stream2'} }); 138 | 139 | }); 140 | 141 | }); 142 | -------------------------------------------------------------------------------- /node/docs/script/prettify/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /node/docs/script/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}preduxBridge django_redux/lib/index", 6 | "variable" 7 | ], 8 | [ 9 | "builtinexternal/ecmascriptexternal.js~array", 10 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array", 11 | "BuiltinExternal/ECMAScriptExternal.js~Array", 12 | "external" 13 | ], 14 | [ 15 | "builtinexternal/ecmascriptexternal.js~arraybuffer", 16 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer", 17 | "BuiltinExternal/ECMAScriptExternal.js~ArrayBuffer", 18 | "external" 19 | ], 20 | [ 21 | "builtinexternal/ecmascriptexternal.js~boolean", 22 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean", 23 | "BuiltinExternal/ECMAScriptExternal.js~Boolean", 24 | "external" 25 | ], 26 | [ 27 | "builtinexternal/ecmascriptexternal.js~dataview", 28 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", 29 | "BuiltinExternal/ECMAScriptExternal.js~DataView", 30 | "external" 31 | ], 32 | [ 33 | "builtinexternal/ecmascriptexternal.js~date", 34 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date", 35 | "BuiltinExternal/ECMAScriptExternal.js~Date", 36 | "external" 37 | ], 38 | [ 39 | "builtinexternal/ecmascriptexternal.js~error", 40 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error", 41 | "BuiltinExternal/ECMAScriptExternal.js~Error", 42 | "external" 43 | ], 44 | [ 45 | "builtinexternal/ecmascriptexternal.js~evalerror", 46 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError", 47 | "BuiltinExternal/ECMAScriptExternal.js~EvalError", 48 | "external" 49 | ], 50 | [ 51 | "builtinexternal/ecmascriptexternal.js~float32array", 52 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array", 53 | "BuiltinExternal/ECMAScriptExternal.js~Float32Array", 54 | "external" 55 | ], 56 | [ 57 | "builtinexternal/ecmascriptexternal.js~float64array", 58 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array", 59 | "BuiltinExternal/ECMAScriptExternal.js~Float64Array", 60 | "external" 61 | ], 62 | [ 63 | "builtinexternal/ecmascriptexternal.js~function", 64 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function", 65 | "BuiltinExternal/ECMAScriptExternal.js~Function", 66 | "external" 67 | ], 68 | [ 69 | "builtinexternal/ecmascriptexternal.js~generator", 70 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator", 71 | "BuiltinExternal/ECMAScriptExternal.js~Generator", 72 | "external" 73 | ], 74 | [ 75 | "builtinexternal/ecmascriptexternal.js~generatorfunction", 76 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction", 77 | "BuiltinExternal/ECMAScriptExternal.js~GeneratorFunction", 78 | "external" 79 | ], 80 | [ 81 | "builtinexternal/ecmascriptexternal.js~infinity", 82 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity", 83 | "BuiltinExternal/ECMAScriptExternal.js~Infinity", 84 | "external" 85 | ], 86 | [ 87 | "builtinexternal/ecmascriptexternal.js~int16array", 88 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array", 89 | "BuiltinExternal/ECMAScriptExternal.js~Int16Array", 90 | "external" 91 | ], 92 | [ 93 | "builtinexternal/ecmascriptexternal.js~int32array", 94 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array", 95 | "BuiltinExternal/ECMAScriptExternal.js~Int32Array", 96 | "external" 97 | ], 98 | [ 99 | "builtinexternal/ecmascriptexternal.js~int8array", 100 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array", 101 | "BuiltinExternal/ECMAScriptExternal.js~Int8Array", 102 | "external" 103 | ], 104 | [ 105 | "builtinexternal/ecmascriptexternal.js~internalerror", 106 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError", 107 | "BuiltinExternal/ECMAScriptExternal.js~InternalError", 108 | "external" 109 | ], 110 | [ 111 | "builtinexternal/ecmascriptexternal.js~json", 112 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON", 113 | "BuiltinExternal/ECMAScriptExternal.js~JSON", 114 | "external" 115 | ], 116 | [ 117 | "builtinexternal/ecmascriptexternal.js~map", 118 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map", 119 | "BuiltinExternal/ECMAScriptExternal.js~Map", 120 | "external" 121 | ], 122 | [ 123 | "builtinexternal/ecmascriptexternal.js~nan", 124 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN", 125 | "BuiltinExternal/ECMAScriptExternal.js~NaN", 126 | "external" 127 | ], 128 | [ 129 | "builtinexternal/ecmascriptexternal.js~number", 130 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number", 131 | "BuiltinExternal/ECMAScriptExternal.js~Number", 132 | "external" 133 | ], 134 | [ 135 | "builtinexternal/ecmascriptexternal.js~object", 136 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object", 137 | "BuiltinExternal/ECMAScriptExternal.js~Object", 138 | "external" 139 | ], 140 | [ 141 | "builtinexternal/ecmascriptexternal.js~promise", 142 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise", 143 | "BuiltinExternal/ECMAScriptExternal.js~Promise", 144 | "external" 145 | ], 146 | [ 147 | "builtinexternal/ecmascriptexternal.js~proxy", 148 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy", 149 | "BuiltinExternal/ECMAScriptExternal.js~Proxy", 150 | "external" 151 | ], 152 | [ 153 | "builtinexternal/ecmascriptexternal.js~rangeerror", 154 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError", 155 | "BuiltinExternal/ECMAScriptExternal.js~RangeError", 156 | "external" 157 | ], 158 | [ 159 | "builtinexternal/ecmascriptexternal.js~referenceerror", 160 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError", 161 | "BuiltinExternal/ECMAScriptExternal.js~ReferenceError", 162 | "external" 163 | ], 164 | [ 165 | "builtinexternal/ecmascriptexternal.js~reflect", 166 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect", 167 | "BuiltinExternal/ECMAScriptExternal.js~Reflect", 168 | "external" 169 | ], 170 | [ 171 | "builtinexternal/ecmascriptexternal.js~regexp", 172 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp", 173 | "BuiltinExternal/ECMAScriptExternal.js~RegExp", 174 | "external" 175 | ], 176 | [ 177 | "builtinexternal/ecmascriptexternal.js~set", 178 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set", 179 | "BuiltinExternal/ECMAScriptExternal.js~Set", 180 | "external" 181 | ], 182 | [ 183 | "builtinexternal/ecmascriptexternal.js~string", 184 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String", 185 | "BuiltinExternal/ECMAScriptExternal.js~String", 186 | "external" 187 | ], 188 | [ 189 | "builtinexternal/ecmascriptexternal.js~symbol", 190 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol", 191 | "BuiltinExternal/ECMAScriptExternal.js~Symbol", 192 | "external" 193 | ], 194 | [ 195 | "builtinexternal/ecmascriptexternal.js~syntaxerror", 196 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError", 197 | "BuiltinExternal/ECMAScriptExternal.js~SyntaxError", 198 | "external" 199 | ], 200 | [ 201 | "builtinexternal/ecmascriptexternal.js~typeerror", 202 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError", 203 | "BuiltinExternal/ECMAScriptExternal.js~TypeError", 204 | "external" 205 | ], 206 | [ 207 | "builtinexternal/ecmascriptexternal.js~urierror", 208 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError", 209 | "BuiltinExternal/ECMAScriptExternal.js~URIError", 210 | "external" 211 | ], 212 | [ 213 | "builtinexternal/ecmascriptexternal.js~uint16array", 214 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array", 215 | "BuiltinExternal/ECMAScriptExternal.js~Uint16Array", 216 | "external" 217 | ], 218 | [ 219 | "builtinexternal/ecmascriptexternal.js~uint32array", 220 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array", 221 | "BuiltinExternal/ECMAScriptExternal.js~Uint32Array", 222 | "external" 223 | ], 224 | [ 225 | "builtinexternal/ecmascriptexternal.js~uint8array", 226 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array", 227 | "BuiltinExternal/ECMAScriptExternal.js~Uint8Array", 228 | "external" 229 | ], 230 | [ 231 | "builtinexternal/ecmascriptexternal.js~uint8clampedarray", 232 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray", 233 | "BuiltinExternal/ECMAScriptExternal.js~Uint8ClampedArray", 234 | "external" 235 | ], 236 | [ 237 | "builtinexternal/ecmascriptexternal.js~weakmap", 238 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap", 239 | "BuiltinExternal/ECMAScriptExternal.js~WeakMap", 240 | "external" 241 | ], 242 | [ 243 | "builtinexternal/ecmascriptexternal.js~weakset", 244 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet", 245 | "BuiltinExternal/ECMAScriptExternal.js~WeakSet", 246 | "external" 247 | ], 248 | [ 249 | "builtinexternal/ecmascriptexternal.js~boolean", 250 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean", 251 | "BuiltinExternal/ECMAScriptExternal.js~boolean", 252 | "external" 253 | ], 254 | [ 255 | "builtinexternal/ecmascriptexternal.js~function", 256 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function", 257 | "BuiltinExternal/ECMAScriptExternal.js~function", 258 | "external" 259 | ], 260 | [ 261 | "builtinexternal/ecmascriptexternal.js~null", 262 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null", 263 | "BuiltinExternal/ECMAScriptExternal.js~null", 264 | "external" 265 | ], 266 | [ 267 | "builtinexternal/ecmascriptexternal.js~number", 268 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number", 269 | "BuiltinExternal/ECMAScriptExternal.js~number", 270 | "external" 271 | ], 272 | [ 273 | "builtinexternal/ecmascriptexternal.js~object", 274 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object", 275 | "BuiltinExternal/ECMAScriptExternal.js~object", 276 | "external" 277 | ], 278 | [ 279 | "builtinexternal/ecmascriptexternal.js~string", 280 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String", 281 | "BuiltinExternal/ECMAScriptExternal.js~string", 282 | "external" 283 | ], 284 | [ 285 | "builtinexternal/ecmascriptexternal.js~undefined", 286 | "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined", 287 | "BuiltinExternal/ECMAScriptExternal.js~undefined", 288 | "external" 289 | ], 290 | [ 291 | "builtinexternal/webapiexternal.js~audiocontext", 292 | "https://developer.mozilla.org/en/docs/Web/API/AudioContext", 293 | "BuiltinExternal/WebAPIExternal.js~AudioContext", 294 | "external" 295 | ], 296 | [ 297 | "builtinexternal/webapiexternal.js~canvasrenderingcontext2d", 298 | "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D", 299 | "BuiltinExternal/WebAPIExternal.js~CanvasRenderingContext2D", 300 | "external" 301 | ], 302 | [ 303 | "builtinexternal/webapiexternal.js~documentfragment", 304 | "https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment", 305 | "BuiltinExternal/WebAPIExternal.js~DocumentFragment", 306 | "external" 307 | ], 308 | [ 309 | "builtinexternal/webapiexternal.js~element", 310 | "https://developer.mozilla.org/en-US/docs/Web/API/Element", 311 | "BuiltinExternal/WebAPIExternal.js~Element", 312 | "external" 313 | ], 314 | [ 315 | "builtinexternal/webapiexternal.js~event", 316 | "https://developer.mozilla.org/en-US/docs/Web/API/Event", 317 | "BuiltinExternal/WebAPIExternal.js~Event", 318 | "external" 319 | ], 320 | [ 321 | "builtinexternal/webapiexternal.js~node", 322 | "https://developer.mozilla.org/en-US/docs/Web/API/Node", 323 | "BuiltinExternal/WebAPIExternal.js~Node", 324 | "external" 325 | ], 326 | [ 327 | "builtinexternal/webapiexternal.js~nodelist", 328 | "https://developer.mozilla.org/en-US/docs/Web/API/NodeList", 329 | "BuiltinExternal/WebAPIExternal.js~NodeList", 330 | "external" 331 | ], 332 | [ 333 | "builtinexternal/webapiexternal.js~xmlhttprequest", 334 | "https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest", 335 | "BuiltinExternal/WebAPIExternal.js~XMLHttpRequest", 336 | "external" 337 | ], 338 | [ 339 | "src/index.js", 340 | "file/src/index.js.html", 341 | "src/index.js", 342 | "file" 343 | ] 344 | ] -------------------------------------------------------------------------------- /node/docs/css/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,300,700); 2 | @import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400italic,600,700); 3 | 4 | * { 5 | margin: 0; 6 | padding: 0; 7 | text-decoration: none; 8 | } 9 | 10 | html 11 | { 12 | font-family: 'Source Sans Pro', 'Roboto', sans-serif; 13 | overflow: auto; 14 | /*font-size: 14px;*/ 15 | /*color: #4d4e53;*/ 16 | /*color: rgba(0, 0, 0, .68);*/ 17 | color: #555; 18 | background-color: #fff; 19 | } 20 | 21 | a { 22 | /*color: #0095dd;*/ 23 | /*color:rgb(37, 138, 175);*/ 24 | color: #039BE5; 25 | } 26 | 27 | code a:hover { 28 | text-decoration: underline; 29 | } 30 | 31 | ul, ol { 32 | padding-left: 20px; 33 | } 34 | 35 | ul li { 36 | list-style: disc; 37 | margin: 4px 0; 38 | } 39 | 40 | ol li { 41 | margin: 4px 0; 42 | } 43 | 44 | h1 { 45 | margin-bottom: 10px; 46 | font-size: 34px; 47 | font-weight: 300; 48 | border-bottom: solid 1px #ddd; 49 | } 50 | 51 | h2 { 52 | margin-top: 24px; 53 | margin-bottom: 10px; 54 | font-size: 20px; 55 | border-bottom: solid 1px #ddd; 56 | font-weight: 300; 57 | } 58 | 59 | h3 { 60 | position: relative; 61 | font-size: 16px; 62 | margin-bottom: 12px; 63 | background-color: #E2E2E2; 64 | padding: 4px; 65 | font-weight: 300; 66 | } 67 | 68 | del { 69 | text-decoration: line-through; 70 | } 71 | 72 | p { 73 | margin-bottom: 15px; 74 | line-height: 1.5; 75 | } 76 | 77 | pre > code { 78 | display: block; 79 | } 80 | 81 | pre.prettyprint, pre > code { 82 | padding: 4px; 83 | margin: 1em 0; 84 | background-color: #f5f5f5; 85 | border-radius: 3px; 86 | } 87 | 88 | pre.prettyprint > code { 89 | margin: 0; 90 | } 91 | 92 | p > code, 93 | li > code { 94 | padding: 0.2em 0.5em; 95 | margin: 0; 96 | font-size: 85%; 97 | background-color: rgba(0,0,0,0.04); 98 | border-radius: 3px; 99 | } 100 | 101 | .import-path pre.prettyprint, 102 | .import-path pre.prettyprint code { 103 | margin: 0; 104 | padding: 0; 105 | border: none; 106 | background: white; 107 | } 108 | 109 | .layout-container { 110 | /*display: flex;*/ 111 | /*flex-direction: row;*/ 112 | /*justify-content: flex-start;*/ 113 | /*align-items: stretch;*/ 114 | } 115 | 116 | .layout-container > header { 117 | height: 40px; 118 | line-height: 40px; 119 | font-size: 16px; 120 | padding: 0 10px; 121 | margin: 0; 122 | position: fixed; 123 | width: 100%; 124 | z-index: 1; 125 | background-color: #fafafa; 126 | top: 0; 127 | border-bottom: solid 1px #ddd; 128 | } 129 | .layout-container > header > a{ 130 | margin: 0 5px; 131 | color: #444; 132 | } 133 | 134 | .layout-container > header > a.repo-url-github { 135 | font-size: 0; 136 | display: inline-block; 137 | width: 20px; 138 | height: 38px; 139 | background: url("../image/github.png") no-repeat center; 140 | background-size: 20px; 141 | vertical-align: top; 142 | } 143 | 144 | .navigation { 145 | position: fixed; 146 | top: 0; 147 | left: 0; 148 | box-sizing: border-box; 149 | width: 250px; 150 | height: 100%; 151 | padding-top: 40px; 152 | padding-left: 15px; 153 | padding-bottom: 2em; 154 | margin-top:1em; 155 | overflow-x: scroll; 156 | box-shadow: rgba(255, 255, 255, 1) -1px 0 0 inset; 157 | border-right: 1px solid #ddd; 158 | } 159 | 160 | .navigation ul { 161 | padding: 0; 162 | } 163 | 164 | .navigation li { 165 | list-style: none; 166 | margin: 4px 0; 167 | white-space: nowrap; 168 | } 169 | 170 | .navigation li a { 171 | color: #666; 172 | } 173 | 174 | .navigation .nav-dir-path { 175 | margin-top: 0.7em; 176 | margin-bottom: 0.25em; 177 | font-size: 0.8em; 178 | color: #aaa; 179 | } 180 | 181 | .kind-class, 182 | .kind-interface, 183 | .kind-function, 184 | .kind-typedef, 185 | .kind-variable, 186 | .kind-external { 187 | margin-left: 0.75em; 188 | width: 1.2em; 189 | height: 1.2em; 190 | display: inline-block; 191 | text-align: center; 192 | border-radius: 0.2em; 193 | margin-right: 0.2em; 194 | font-weight: bold; 195 | } 196 | 197 | .kind-class { 198 | color: #009800; 199 | background-color: #bfe5bf; 200 | } 201 | 202 | .kind-interface { 203 | color: #fbca04; 204 | background-color: #fef2c0; 205 | } 206 | 207 | .kind-function { 208 | color: #6b0090; 209 | background-color: #d6bdde; 210 | } 211 | 212 | .kind-variable { 213 | color: #eb6420; 214 | background-color: #fad8c7; 215 | } 216 | 217 | .kind-typedef { 218 | color: #db001e; 219 | background-color: #edbec3; 220 | } 221 | 222 | .kind-external { 223 | color: #0738c3; 224 | background-color: #bbcbea; 225 | } 226 | 227 | h1 .version, 228 | h1 .url a { 229 | font-size: 14px; 230 | color: #aaa; 231 | } 232 | 233 | .content { 234 | margin-top: 40px; 235 | margin-left: 250px; 236 | padding: 10px 50px 10px 20px; 237 | } 238 | 239 | .header-notice { 240 | font-size: 14px; 241 | color: #aaa; 242 | margin: 0; 243 | } 244 | 245 | .expression-extends .prettyprint { 246 | margin-left: 10px; 247 | background: white; 248 | } 249 | 250 | .extends-chain { 251 | border-bottom: 1px solid#ddd; 252 | padding-bottom: 10px; 253 | margin-bottom: 10px; 254 | } 255 | 256 | .extends-chain span:nth-of-type(1) { 257 | padding-left: 10px; 258 | } 259 | 260 | .extends-chain > div { 261 | margin: 5px 0; 262 | } 263 | 264 | .description table { 265 | font-size: 14px; 266 | border-spacing: 0; 267 | border: 0; 268 | border-collapse: collapse; 269 | } 270 | 271 | .description thead { 272 | background: #999; 273 | color: white; 274 | } 275 | 276 | .description table td, 277 | .description table th { 278 | border: solid 1px #ddd; 279 | padding: 4px; 280 | font-weight: normal; 281 | } 282 | 283 | .flat-list ul { 284 | padding-left: 0; 285 | } 286 | 287 | .flat-list li { 288 | display: inline; 289 | list-style: none; 290 | } 291 | 292 | table.summary { 293 | width: 100%; 294 | margin: 10px 0; 295 | border-spacing: 0; 296 | border: 0; 297 | border-collapse: collapse; 298 | } 299 | 300 | table.summary thead { 301 | background: #999; 302 | color: white; 303 | } 304 | 305 | table.summary td { 306 | border: solid 1px #ddd; 307 | padding: 4px 10px; 308 | } 309 | 310 | table.summary tbody td:nth-child(1) { 311 | text-align: right; 312 | white-space: nowrap; 313 | min-width: 64px; 314 | vertical-align: top; 315 | } 316 | 317 | table.summary tbody td:nth-child(2) { 318 | width: 100%; 319 | border-right: none; 320 | } 321 | 322 | table.summary tbody td:nth-child(3) { 323 | white-space: nowrap; 324 | border-left: none; 325 | vertical-align: top; 326 | } 327 | 328 | table.summary td > div:nth-of-type(2) { 329 | padding-top: 4px; 330 | padding-left: 15px; 331 | } 332 | 333 | table.summary td p { 334 | margin-bottom: 0; 335 | } 336 | 337 | .inherited-summary thead td { 338 | padding-left: 2px; 339 | } 340 | 341 | .inherited-summary thead a { 342 | color: white; 343 | } 344 | 345 | .inherited-summary .summary tbody { 346 | display: none; 347 | } 348 | 349 | .inherited-summary .summary .toggle { 350 | padding: 0 4px; 351 | font-size: 12px; 352 | cursor: pointer; 353 | } 354 | .inherited-summary .summary .toggle.closed:before { 355 | content: "▶"; 356 | } 357 | .inherited-summary .summary .toggle.opened:before { 358 | content: "▼"; 359 | } 360 | 361 | .member, .method { 362 | margin-bottom: 24px; 363 | } 364 | 365 | table.params { 366 | width: 100%; 367 | margin: 10px 0; 368 | border-spacing: 0; 369 | border: 0; 370 | border-collapse: collapse; 371 | } 372 | 373 | table.params thead { 374 | background: #eee; 375 | color: #aaa; 376 | } 377 | 378 | table.params td { 379 | padding: 4px; 380 | border: solid 1px #ddd; 381 | } 382 | 383 | table.params td p { 384 | margin: 0; 385 | } 386 | 387 | .content .detail > * { 388 | margin: 15px 0; 389 | } 390 | 391 | .content .detail > h3 { 392 | color: black; 393 | } 394 | 395 | .content .detail > div { 396 | margin-left: 10px; 397 | } 398 | 399 | .content .detail > .import-path { 400 | margin-top: -8px; 401 | } 402 | 403 | .content .detail + .detail { 404 | margin-top: 30px; 405 | } 406 | 407 | .content .detail .throw td:first-child { 408 | padding-right: 10px; 409 | } 410 | 411 | .content .detail h4 + :not(pre) { 412 | padding-left: 0; 413 | margin-left: 10px; 414 | } 415 | 416 | .content .detail h4 + ul li { 417 | list-style: none; 418 | } 419 | 420 | .return-param * { 421 | display: inline; 422 | } 423 | 424 | .argument-params { 425 | margin-bottom: 20px; 426 | } 427 | 428 | .return-type { 429 | padding-right: 10px; 430 | font-weight: normal; 431 | } 432 | 433 | .return-desc { 434 | margin-left: 10px; 435 | margin-top: 4px; 436 | } 437 | 438 | .return-desc p { 439 | margin: 0; 440 | } 441 | 442 | .deprecated, .experimental, .instance-docs { 443 | border-left: solid 5px orange; 444 | padding-left: 4px; 445 | margin: 4px 0; 446 | } 447 | 448 | tr.listen p, 449 | tr.throw p, 450 | tr.emit p{ 451 | margin-bottom: 10px; 452 | } 453 | 454 | .version, .since { 455 | color: #aaa; 456 | } 457 | 458 | h3 .right-info { 459 | position: absolute; 460 | right: 4px; 461 | font-size: 14px; 462 | } 463 | 464 | .version + .since:before { 465 | content: '| '; 466 | } 467 | 468 | .see { 469 | margin-top: 10px; 470 | } 471 | 472 | .see h4 { 473 | margin: 4px 0; 474 | } 475 | 476 | .content .detail h4 + .example-doc { 477 | margin: 6px 0; 478 | } 479 | 480 | .example-caption { 481 | position: relative; 482 | bottom: -1px; 483 | display: inline-block; 484 | padding: 4px; 485 | font-style: italic; 486 | background-color: #f5f5f5; 487 | font-weight: bold; 488 | border-radius: 3px; 489 | border-bottom-left-radius: 0; 490 | border-bottom-right-radius: 0; 491 | } 492 | 493 | .example-caption + pre.source-code { 494 | margin-top: 0; 495 | border-top-left-radius: 0; 496 | } 497 | 498 | footer, .file-footer { 499 | text-align: right; 500 | font-style: italic; 501 | font-weight: 100; 502 | font-size: 13px; 503 | margin-right: 50px; 504 | margin-left: 270px; 505 | border-top: 1px solid #ddd; 506 | padding-top: 30px; 507 | margin-top: 20px; 508 | padding-bottom: 10px; 509 | } 510 | 511 | footer img { 512 | width: 24px; 513 | vertical-align: middle; 514 | padding-left: 4px; 515 | position: relative; 516 | top: -3px; 517 | opacity: 0.6; 518 | } 519 | 520 | pre.source-code { 521 | background: #f5f5f5; 522 | padding: 4px; 523 | } 524 | 525 | pre.raw-source-code > code { 526 | padding: 0; 527 | margin: 0; 528 | } 529 | 530 | pre.source-code.line-number { 531 | padding: 0; 532 | } 533 | 534 | pre.source-code ol { 535 | background: #eee; 536 | padding-left: 40px; 537 | } 538 | 539 | pre.source-code li { 540 | background: white; 541 | padding-left: 4px; 542 | list-style: decimal; 543 | margin: 0; 544 | } 545 | 546 | pre.source-code.line-number li.active { 547 | background: rgb(255, 255, 150); 548 | } 549 | 550 | pre.source-code.line-number li.error-line { 551 | background: #ffb8bf; 552 | } 553 | 554 | table.files-summary { 555 | width: 100%; 556 | margin: 10px 0; 557 | border-spacing: 0; 558 | border: 0; 559 | border-collapse: collapse; 560 | text-align: right; 561 | } 562 | 563 | table.files-summary tbody tr:hover { 564 | background: #eee; 565 | } 566 | 567 | table.files-summary td:first-child, 568 | table.files-summary td:nth-of-type(2) { 569 | text-align: left; 570 | } 571 | 572 | table.files-summary[data-use-coverage="false"] td.coverage { 573 | display: none; 574 | } 575 | 576 | table.files-summary thead { 577 | background: #999; 578 | color: white; 579 | } 580 | 581 | table.files-summary td { 582 | border: solid 1px #ddd; 583 | padding: 4px 10px; 584 | vertical-align: top; 585 | } 586 | 587 | table.files-summary td.identifiers > span { 588 | display: block; 589 | margin-top: 4px; 590 | } 591 | table.files-summary td.identifiers > span:first-child { 592 | margin-top: 0; 593 | } 594 | 595 | table.files-summary .coverage-count { 596 | font-size: 12px; 597 | color: #aaa; 598 | display: inline-block; 599 | min-width: 40px; 600 | } 601 | 602 | .total-coverage-count { 603 | position: relative; 604 | bottom: 2px; 605 | font-size: 12px; 606 | color: #666; 607 | font-weight: 500; 608 | padding-left: 5px; 609 | } 610 | 611 | table.test-summary thead { 612 | background: #999; 613 | color: white; 614 | } 615 | 616 | table.test-summary thead .test-description { 617 | width: 50%; 618 | } 619 | 620 | table.test-summary { 621 | width: 100%; 622 | margin: 10px 0; 623 | border-spacing: 0; 624 | border: 0; 625 | border-collapse: collapse; 626 | } 627 | 628 | table.test-summary thead .test-count { 629 | width: 3em; 630 | } 631 | 632 | table.test-summary tbody tr:hover { 633 | background-color: #eee; 634 | } 635 | 636 | table.test-summary td { 637 | border: solid 1px #ddd; 638 | padding: 4px 10px; 639 | vertical-align: top; 640 | } 641 | 642 | table.test-summary td p { 643 | margin: 0; 644 | } 645 | 646 | table.test-summary tr.test-describe .toggle { 647 | display: inline-block; 648 | float: left; 649 | margin-right: 4px; 650 | cursor: pointer; 651 | font-size: 0.8em; 652 | padding-top: 0.25em; 653 | } 654 | 655 | table.test-summary tr.test-describe .toggle.opened:before { 656 | content: '▼'; 657 | } 658 | 659 | table.test-summary tr.test-describe .toggle.closed:before { 660 | content: '▶'; 661 | } 662 | 663 | table.test-summary .test-target > span { 664 | display: block; 665 | margin-top: 4px; 666 | } 667 | table.test-summary .test-target > span:first-child { 668 | margin-top: 0; 669 | } 670 | 671 | .inner-link-active { 672 | background: rgb(255, 255, 150); 673 | } 674 | 675 | /* search box */ 676 | .search-box { 677 | position: absolute; 678 | top: 10px; 679 | right: 50px; 680 | padding-right: 8px; 681 | padding-bottom: 10px; 682 | line-height: normal; 683 | font-size: 12px; 684 | } 685 | 686 | .search-box img { 687 | width: 20px; 688 | vertical-align: top; 689 | } 690 | 691 | .search-input { 692 | display: inline; 693 | visibility: hidden; 694 | width: 0; 695 | padding: 2px; 696 | height: 1.5em; 697 | outline: none; 698 | background: transparent; 699 | border: 1px #0af; 700 | border-style: none none solid none; 701 | vertical-align: bottom; 702 | } 703 | 704 | .search-input-edge { 705 | display: none; 706 | width: 1px; 707 | height: 5px; 708 | background-color: #0af; 709 | vertical-align: bottom; 710 | } 711 | 712 | .search-result { 713 | position: absolute; 714 | display: none; 715 | height: 600px; 716 | width: 100%; 717 | padding: 0; 718 | margin-top: 5px; 719 | margin-left: 24px; 720 | background: white; 721 | box-shadow: 1px 1px 4px rgb(0,0,0); 722 | white-space: nowrap; 723 | overflow-y: scroll; 724 | } 725 | 726 | .search-result-import-path { 727 | color: #aaa; 728 | font-size: 12px; 729 | } 730 | 731 | .search-result li { 732 | list-style: none; 733 | padding: 2px 4px; 734 | } 735 | 736 | .search-result li a { 737 | display: block; 738 | } 739 | 740 | .search-result li.selected { 741 | background: #ddd; 742 | } 743 | 744 | .search-result li.search-separator { 745 | background: rgb(37, 138, 175); 746 | color: white; 747 | } 748 | 749 | .search-box.active .search-input { 750 | visibility: visible; 751 | transition: width 0.2s ease-out; 752 | width: 300px; 753 | } 754 | 755 | .search-box.active .search-input-edge { 756 | display: inline-block; 757 | } 758 | 759 | .github-markdown .manual-toc { 760 | padding-left: 0; 761 | } 762 | 763 | /** manual */ 764 | 765 | .manual-index .manual-cards { 766 | display: flex; 767 | flex-wrap: wrap; 768 | } 769 | 770 | .manual-index .manual-card-wrap { 771 | width: 280px; 772 | padding: 10px 20px 10px 0; 773 | box-sizing: border-box; 774 | } 775 | 776 | .manual-index .manual-card-wrap > h1 { 777 | margin: 0; 778 | font-size: 1em; 779 | font-weight: 600; 780 | padding: 0.2em 0 0.2em 0.5em; 781 | border-radius: 0.1em 0.1em 0 0; 782 | border: none; 783 | } 784 | 785 | .manual-index .manual-card-wrap > h1 span { 786 | color: #555; 787 | } 788 | 789 | .manual-index .manual-card { 790 | height: 200px; 791 | overflow: hidden; 792 | border: solid 1px rgba(230, 230, 230, 0.84); 793 | border-radius: 0 0 0.1em 0.1em; 794 | padding: 8px; 795 | position: relative; 796 | border-top: none; 797 | } 798 | 799 | .manual-index .manual-card > div { 800 | transform: scale(0.4); 801 | transform-origin: 0 0; 802 | width: 250%; 803 | } 804 | 805 | .manual-index .manual-card > a { 806 | position: absolute; 807 | top: 0; 808 | left: 0; 809 | width: 100%; 810 | height: 100%; 811 | background: rgba(210, 210, 210, 0.1); 812 | } 813 | 814 | .manual-index .manual-card > a:hover { 815 | background: none; 816 | } 817 | 818 | .manual-index .manual-badge { 819 | margin: 0; 820 | } 821 | 822 | .manual-index .manual-user-index { 823 | margin-bottom: 1em; 824 | border-bottom: solid 1px #ddd; 825 | } 826 | 827 | .manual-root .navigation { 828 | padding-left: 4px; 829 | margin-top: 4px; 830 | } 831 | 832 | .navigation .manual-toc { 833 | margin-top: -0.25em; 834 | } 835 | 836 | .navigation .manual-toc-root > div { 837 | padding-top: 1px; 838 | padding-left: 0.25em; 839 | padding-right: 0.75em; 840 | } 841 | 842 | .github-markdown .manual-toc-title a { 843 | color: inherit; 844 | } 845 | 846 | .manual-breadcrumb-list { 847 | font-size: 0.8em; 848 | margin-bottom: 1em; 849 | } 850 | 851 | .manual-toc-title a:hover { 852 | color: #039BE5; 853 | } 854 | 855 | .manual-toc li { 856 | margin: 0.75em 0; 857 | list-style-type: none; 858 | } 859 | 860 | .navigation .manual-toc [class^="indent-h"] a { 861 | color: #666; 862 | } 863 | 864 | .navigation .manual-toc .indent-h1 a { 865 | color: #555; 866 | font-weight: 600; 867 | display: block; 868 | } 869 | 870 | .manual-toc .indent-h1 { 871 | display: block; 872 | margin: 1em 0 0 0.25em; 873 | padding: 0.2em 0 0.2em 0.5em; 874 | border-radius: 0.1em; 875 | } 876 | .manual-toc .indent-h2 { 877 | display: none; 878 | margin-left: 1.5em; 879 | } 880 | .manual-toc .indent-h3 { 881 | display: none; 882 | margin-left: 2.5em; 883 | } 884 | .manual-toc .indent-h4 { 885 | display: none; 886 | margin-left: 3.5em; 887 | } 888 | .manual-toc .indent-h5 { 889 | display: none; 890 | margin-left: 4.5em; 891 | } 892 | 893 | .manual-color { 894 | position: relative; 895 | } 896 | 897 | .manual-color:after { 898 | content: attr(data-section-count); 899 | font-size: 0.5em; 900 | opacity: 0.5; 901 | position: absolute; 902 | right: 0.5em; 903 | top: 0.5em; 904 | } 905 | 906 | .manual-color-overview, 907 | .manual-color-design { 908 | color: #db001e; 909 | background-color: #edbec3; 910 | } 911 | 912 | .manual-color-installation, 913 | .manual-color-tutorial, 914 | .manual-color-usage, 915 | .manual-color-configuration, 916 | .manual-color-advanced { 917 | color: #009800; 918 | background-color: #bfe5bf; 919 | } 920 | 921 | .manual-color-example { 922 | color: #eb6420; 923 | background-color: #fad8c7; 924 | } 925 | 926 | .manual-color-reference { 927 | color: #6b0090; 928 | background-color: #d6bdde; 929 | } 930 | 931 | .manual-color-faq, 932 | .manual-color-changelog { 933 | color: #0738c3; 934 | background-color: #bbcbea; 935 | } 936 | 937 | .manual-nav li { 938 | margin: 0.75em 0; 939 | } 940 | 941 | /* github markdown */ 942 | .github-markdown { 943 | font-size: 16px; 944 | } 945 | 946 | .github-markdown h1, 947 | .github-markdown h2, 948 | .github-markdown h3, 949 | .github-markdown h4, 950 | .github-markdown h5 { 951 | margin-top: 1em; 952 | margin-bottom: 16px; 953 | font-weight: bold; 954 | padding: 0; 955 | } 956 | 957 | .github-markdown h1:nth-of-type(1) { 958 | margin-top: 0; 959 | } 960 | 961 | .github-markdown h1 { 962 | font-size: 2em; 963 | padding-bottom: 0.3em; 964 | } 965 | 966 | .github-markdown h2 { 967 | font-size: 1.75em; 968 | padding-bottom: 0.3em; 969 | } 970 | 971 | .github-markdown h3 { 972 | font-size: 1.5em; 973 | background-color: transparent; 974 | } 975 | 976 | .github-markdown h4 { 977 | font-size: 1.25em; 978 | } 979 | 980 | .github-markdown h5 { 981 | font-size: 1em; 982 | } 983 | 984 | .github-markdown ul, .github-markdown ol { 985 | padding-left: 2em; 986 | } 987 | 988 | .github-markdown pre > code { 989 | font-size: 0.85em; 990 | } 991 | 992 | .github-markdown table { 993 | margin-bottom: 1em; 994 | border-collapse: collapse; 995 | border-spacing: 0; 996 | } 997 | 998 | .github-markdown table tr { 999 | background-color: #fff; 1000 | border-top: 1px solid #ccc; 1001 | } 1002 | 1003 | .github-markdown table th, 1004 | .github-markdown table td { 1005 | padding: 6px 13px; 1006 | border: 1px solid #ddd; 1007 | } 1008 | 1009 | .github-markdown table tr:nth-child(2n) { 1010 | background-color: #f8f8f8; 1011 | } 1012 | 1013 | .github-markdown hr { 1014 | border-right: 0; 1015 | border-bottom: 1px solid #e5e5e5; 1016 | border-left: 0; 1017 | border-top: 0; 1018 | } 1019 | 1020 | /** badge(.svg) does not have border */ 1021 | .github-markdown img:not([src*=".svg"]) { 1022 | max-width: 100%; 1023 | box-shadow: 1px 1px 1px rgba(0,0,0,0.5); 1024 | } 1025 | -------------------------------------------------------------------------------- /node/docs/dump.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__docId__": 0, 4 | "kind": "file", 5 | "name": "src/index.js", 6 | "content": "import { WebSocketBridge } from 'django-channels';\n\n\nexport class ReduxBridge extends WebSocketBridge {\n /**\n * Starts listening for messages on the websocket, demultiplexing if necessary.\n *\n * @param {Object} store Your redux store.\n * @param {Function} [cb] Callback to be execute when a message\n * arrives. The callback will receive `store`, `action` and `stream` parameters.\n * By default it will call `store.dispatch(action)`;\n *\n * @example\n * const webSocketBridge = new WebSocketBridge();\n * webSocketBridge.connect();\n * webSocketBridge.listen(store);\n */\n listen(store, cb = this.storeDispatch) {\n this.default_cb = cb;\n this.socket.onmessage = (event) => {\n const msg = JSON.parse(event.data);\n let action;\n let stream;\n if (msg.stream !== undefined) {\n action = msg.payload;\n stream = msg.stream;\n const stream_cb = this.streams[stream];\n stream_cb ? stream_cb(store, action, stream) : null;\n } else {\n action = msg;\n stream = null;\n this.default_cb ? this.default_cb(store, action, stream) : null;\n }\n };\n\n this.socket.onopen = () => {\n const state = store.getState();\n\n if (state.currentUser !== null) {\n // the connection was dropped. Call the recovery logic\n this.options.onreconnect(state);\n }\n };\n }\n\n storeDispatch(store, action, stream) {\n return store.dispatch(action);\n }\n\n}\n\n/**\n * Convenience singleton for `ReduxSocketBridge`.\n * @example\n * import { ReduxBridge } from 'django_redux';\n *\n * ReduxBridge.connect();\n * ReduxBridge.listen(store);\n *\n * @type {ReduxSocketBridge}\n */\nexport const reduxBridge = new ReduxBridge();\n", 7 | "static": true, 8 | "longname": "src/index.js", 9 | "access": null, 10 | "description": null, 11 | "lineNumber": 1 12 | }, 13 | { 14 | "__docId__": 1, 15 | "kind": "class", 16 | "name": "ReduxBridge", 17 | "memberof": "src/index.js", 18 | "static": true, 19 | "longname": "src/index.js~ReduxBridge", 20 | "access": null, 21 | "export": true, 22 | "importPath": "django_redux/lib/index", 23 | "importStyle": "{ReduxBridge}", 24 | "description": null, 25 | "lineNumber": 4, 26 | "undocument": true, 27 | "unknown": [ 28 | { 29 | "tagName": "@_undocument", 30 | "tagValue": "" 31 | } 32 | ], 33 | "interface": false, 34 | "extends": [ 35 | "django-channels~WebSocketBridge" 36 | ] 37 | }, 38 | { 39 | "__docId__": 2, 40 | "kind": "method", 41 | "name": "listen", 42 | "memberof": "src/index.js~ReduxBridge", 43 | "generator": false, 44 | "async": false, 45 | "static": false, 46 | "longname": "src/index.js~ReduxBridge#listen", 47 | "access": null, 48 | "description": "Starts listening for messages on the websocket, demultiplexing if necessary.", 49 | "examples": [ 50 | "const webSocketBridge = new WebSocketBridge();\nwebSocketBridge.connect();\nwebSocketBridge.listen(store);" 51 | ], 52 | "lineNumber": 18, 53 | "params": [ 54 | { 55 | "nullable": null, 56 | "types": [ 57 | "Object" 58 | ], 59 | "spread": false, 60 | "optional": false, 61 | "name": "store", 62 | "description": "Your redux store." 63 | }, 64 | { 65 | "nullable": null, 66 | "types": [ 67 | "Function" 68 | ], 69 | "spread": false, 70 | "optional": true, 71 | "name": "cb", 72 | "description": "Callback to be execute when a message\narrives. The callback will receive `store`, `action` and `stream` parameters.\nBy default it will call `store.dispatch(action)`;" 73 | } 74 | ] 75 | }, 76 | { 77 | "__docId__": 3, 78 | "kind": "member", 79 | "name": "default_cb", 80 | "memberof": "src/index.js~ReduxBridge", 81 | "static": false, 82 | "longname": "src/index.js~ReduxBridge#default_cb", 83 | "access": null, 84 | "description": null, 85 | "lineNumber": 19, 86 | "undocument": true, 87 | "unknown": [ 88 | { 89 | "tagName": "@_undocument", 90 | "tagValue": "" 91 | } 92 | ], 93 | "type": { 94 | "types": [ 95 | "*" 96 | ] 97 | } 98 | }, 99 | { 100 | "__docId__": 4, 101 | "kind": "method", 102 | "name": "storeDispatch", 103 | "memberof": "src/index.js~ReduxBridge", 104 | "generator": false, 105 | "async": false, 106 | "static": false, 107 | "longname": "src/index.js~ReduxBridge#storeDispatch", 108 | "access": null, 109 | "description": null, 110 | "lineNumber": 46, 111 | "undocument": true, 112 | "unknown": [ 113 | { 114 | "tagName": "@_undocument", 115 | "tagValue": "" 116 | } 117 | ], 118 | "params": [ 119 | { 120 | "name": "store", 121 | "types": [ 122 | "*" 123 | ] 124 | }, 125 | { 126 | "name": "action", 127 | "types": [ 128 | "*" 129 | ] 130 | }, 131 | { 132 | "name": "stream", 133 | "types": [ 134 | "*" 135 | ] 136 | } 137 | ], 138 | "return": { 139 | "types": [ 140 | "*" 141 | ] 142 | } 143 | }, 144 | { 145 | "__docId__": 5, 146 | "kind": "variable", 147 | "name": "reduxBridge", 148 | "memberof": "src/index.js", 149 | "static": true, 150 | "longname": "src/index.js~reduxBridge", 151 | "access": null, 152 | "export": true, 153 | "importPath": "django_redux/lib/index", 154 | "importStyle": "{reduxBridge}", 155 | "description": "Convenience singleton for `ReduxSocketBridge`.", 156 | "examples": [ 157 | "import { ReduxBridge } from 'django_redux';\n\nReduxBridge.connect();\nReduxBridge.listen(store);" 158 | ], 159 | "lineNumber": 62, 160 | "type": { 161 | "nullable": null, 162 | "types": [ 163 | "ReduxSocketBridge" 164 | ], 165 | "spread": false, 166 | "description": null 167 | } 168 | }, 169 | { 170 | "__docId__": 7, 171 | "kind": "external", 172 | "name": "Infinity", 173 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity", 174 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 175 | "static": true, 176 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Infinity", 177 | "access": null, 178 | "description": "", 179 | "builtinExternal": true 180 | }, 181 | { 182 | "__docId__": 8, 183 | "kind": "external", 184 | "name": "NaN", 185 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN", 186 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 187 | "static": true, 188 | "longname": "BuiltinExternal/ECMAScriptExternal.js~NaN", 189 | "access": null, 190 | "description": "", 191 | "builtinExternal": true 192 | }, 193 | { 194 | "__docId__": 9, 195 | "kind": "external", 196 | "name": "undefined", 197 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined", 198 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 199 | "static": true, 200 | "longname": "BuiltinExternal/ECMAScriptExternal.js~undefined", 201 | "access": null, 202 | "description": "", 203 | "builtinExternal": true 204 | }, 205 | { 206 | "__docId__": 10, 207 | "kind": "external", 208 | "name": "null", 209 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null", 210 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 211 | "static": true, 212 | "longname": "BuiltinExternal/ECMAScriptExternal.js~null", 213 | "access": null, 214 | "description": "", 215 | "builtinExternal": true 216 | }, 217 | { 218 | "__docId__": 11, 219 | "kind": "external", 220 | "name": "Object", 221 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object", 222 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 223 | "static": true, 224 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Object", 225 | "access": null, 226 | "description": "", 227 | "builtinExternal": true 228 | }, 229 | { 230 | "__docId__": 12, 231 | "kind": "external", 232 | "name": "object", 233 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object", 234 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 235 | "static": true, 236 | "longname": "BuiltinExternal/ECMAScriptExternal.js~object", 237 | "access": null, 238 | "description": "", 239 | "builtinExternal": true 240 | }, 241 | { 242 | "__docId__": 13, 243 | "kind": "external", 244 | "name": "Function", 245 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function", 246 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 247 | "static": true, 248 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Function", 249 | "access": null, 250 | "description": "", 251 | "builtinExternal": true 252 | }, 253 | { 254 | "__docId__": 14, 255 | "kind": "external", 256 | "name": "function", 257 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function", 258 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 259 | "static": true, 260 | "longname": "BuiltinExternal/ECMAScriptExternal.js~function", 261 | "access": null, 262 | "description": "", 263 | "builtinExternal": true 264 | }, 265 | { 266 | "__docId__": 15, 267 | "kind": "external", 268 | "name": "Boolean", 269 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean", 270 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 271 | "static": true, 272 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Boolean", 273 | "access": null, 274 | "description": "", 275 | "builtinExternal": true 276 | }, 277 | { 278 | "__docId__": 16, 279 | "kind": "external", 280 | "name": "boolean", 281 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean", 282 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 283 | "static": true, 284 | "longname": "BuiltinExternal/ECMAScriptExternal.js~boolean", 285 | "access": null, 286 | "description": "", 287 | "builtinExternal": true 288 | }, 289 | { 290 | "__docId__": 17, 291 | "kind": "external", 292 | "name": "Symbol", 293 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol", 294 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 295 | "static": true, 296 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Symbol", 297 | "access": null, 298 | "description": "", 299 | "builtinExternal": true 300 | }, 301 | { 302 | "__docId__": 18, 303 | "kind": "external", 304 | "name": "Error", 305 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error", 306 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 307 | "static": true, 308 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Error", 309 | "access": null, 310 | "description": "", 311 | "builtinExternal": true 312 | }, 313 | { 314 | "__docId__": 19, 315 | "kind": "external", 316 | "name": "EvalError", 317 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError", 318 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 319 | "static": true, 320 | "longname": "BuiltinExternal/ECMAScriptExternal.js~EvalError", 321 | "access": null, 322 | "description": "", 323 | "builtinExternal": true 324 | }, 325 | { 326 | "__docId__": 20, 327 | "kind": "external", 328 | "name": "InternalError", 329 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError", 330 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 331 | "static": true, 332 | "longname": "BuiltinExternal/ECMAScriptExternal.js~InternalError", 333 | "access": null, 334 | "description": "", 335 | "builtinExternal": true 336 | }, 337 | { 338 | "__docId__": 21, 339 | "kind": "external", 340 | "name": "RangeError", 341 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError", 342 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 343 | "static": true, 344 | "longname": "BuiltinExternal/ECMAScriptExternal.js~RangeError", 345 | "access": null, 346 | "description": "", 347 | "builtinExternal": true 348 | }, 349 | { 350 | "__docId__": 22, 351 | "kind": "external", 352 | "name": "ReferenceError", 353 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError", 354 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 355 | "static": true, 356 | "longname": "BuiltinExternal/ECMAScriptExternal.js~ReferenceError", 357 | "access": null, 358 | "description": "", 359 | "builtinExternal": true 360 | }, 361 | { 362 | "__docId__": 23, 363 | "kind": "external", 364 | "name": "SyntaxError", 365 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError", 366 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 367 | "static": true, 368 | "longname": "BuiltinExternal/ECMAScriptExternal.js~SyntaxError", 369 | "access": null, 370 | "description": "", 371 | "builtinExternal": true 372 | }, 373 | { 374 | "__docId__": 24, 375 | "kind": "external", 376 | "name": "TypeError", 377 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError", 378 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 379 | "static": true, 380 | "longname": "BuiltinExternal/ECMAScriptExternal.js~TypeError", 381 | "access": null, 382 | "description": "", 383 | "builtinExternal": true 384 | }, 385 | { 386 | "__docId__": 25, 387 | "kind": "external", 388 | "name": "URIError", 389 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError", 390 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 391 | "static": true, 392 | "longname": "BuiltinExternal/ECMAScriptExternal.js~URIError", 393 | "access": null, 394 | "description": "", 395 | "builtinExternal": true 396 | }, 397 | { 398 | "__docId__": 26, 399 | "kind": "external", 400 | "name": "Number", 401 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number", 402 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 403 | "static": true, 404 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Number", 405 | "access": null, 406 | "description": "", 407 | "builtinExternal": true 408 | }, 409 | { 410 | "__docId__": 27, 411 | "kind": "external", 412 | "name": "number", 413 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number", 414 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 415 | "static": true, 416 | "longname": "BuiltinExternal/ECMAScriptExternal.js~number", 417 | "access": null, 418 | "description": "", 419 | "builtinExternal": true 420 | }, 421 | { 422 | "__docId__": 28, 423 | "kind": "external", 424 | "name": "Date", 425 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date", 426 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 427 | "static": true, 428 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Date", 429 | "access": null, 430 | "description": "", 431 | "builtinExternal": true 432 | }, 433 | { 434 | "__docId__": 29, 435 | "kind": "external", 436 | "name": "String", 437 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String", 438 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 439 | "static": true, 440 | "longname": "BuiltinExternal/ECMAScriptExternal.js~String", 441 | "access": null, 442 | "description": "", 443 | "builtinExternal": true 444 | }, 445 | { 446 | "__docId__": 30, 447 | "kind": "external", 448 | "name": "string", 449 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String", 450 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 451 | "static": true, 452 | "longname": "BuiltinExternal/ECMAScriptExternal.js~string", 453 | "access": null, 454 | "description": "", 455 | "builtinExternal": true 456 | }, 457 | { 458 | "__docId__": 31, 459 | "kind": "external", 460 | "name": "RegExp", 461 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp", 462 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 463 | "static": true, 464 | "longname": "BuiltinExternal/ECMAScriptExternal.js~RegExp", 465 | "access": null, 466 | "description": "", 467 | "builtinExternal": true 468 | }, 469 | { 470 | "__docId__": 32, 471 | "kind": "external", 472 | "name": "Array", 473 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array", 474 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 475 | "static": true, 476 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Array", 477 | "access": null, 478 | "description": "", 479 | "builtinExternal": true 480 | }, 481 | { 482 | "__docId__": 33, 483 | "kind": "external", 484 | "name": "Int8Array", 485 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array", 486 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 487 | "static": true, 488 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Int8Array", 489 | "access": null, 490 | "description": "", 491 | "builtinExternal": true 492 | }, 493 | { 494 | "__docId__": 34, 495 | "kind": "external", 496 | "name": "Uint8Array", 497 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array", 498 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 499 | "static": true, 500 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint8Array", 501 | "access": null, 502 | "description": "", 503 | "builtinExternal": true 504 | }, 505 | { 506 | "__docId__": 35, 507 | "kind": "external", 508 | "name": "Uint8ClampedArray", 509 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray", 510 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 511 | "static": true, 512 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint8ClampedArray", 513 | "access": null, 514 | "description": "", 515 | "builtinExternal": true 516 | }, 517 | { 518 | "__docId__": 36, 519 | "kind": "external", 520 | "name": "Int16Array", 521 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array", 522 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 523 | "static": true, 524 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Int16Array", 525 | "access": null, 526 | "description": "", 527 | "builtinExternal": true 528 | }, 529 | { 530 | "__docId__": 37, 531 | "kind": "external", 532 | "name": "Uint16Array", 533 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array", 534 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 535 | "static": true, 536 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint16Array", 537 | "access": null, 538 | "description": "", 539 | "builtinExternal": true 540 | }, 541 | { 542 | "__docId__": 38, 543 | "kind": "external", 544 | "name": "Int32Array", 545 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array", 546 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 547 | "static": true, 548 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Int32Array", 549 | "access": null, 550 | "description": "", 551 | "builtinExternal": true 552 | }, 553 | { 554 | "__docId__": 39, 555 | "kind": "external", 556 | "name": "Uint32Array", 557 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array", 558 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 559 | "static": true, 560 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Uint32Array", 561 | "access": null, 562 | "description": "", 563 | "builtinExternal": true 564 | }, 565 | { 566 | "__docId__": 40, 567 | "kind": "external", 568 | "name": "Float32Array", 569 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array", 570 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 571 | "static": true, 572 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Float32Array", 573 | "access": null, 574 | "description": "", 575 | "builtinExternal": true 576 | }, 577 | { 578 | "__docId__": 41, 579 | "kind": "external", 580 | "name": "Float64Array", 581 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array", 582 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 583 | "static": true, 584 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Float64Array", 585 | "access": null, 586 | "description": "", 587 | "builtinExternal": true 588 | }, 589 | { 590 | "__docId__": 42, 591 | "kind": "external", 592 | "name": "Map", 593 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map", 594 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 595 | "static": true, 596 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Map", 597 | "access": null, 598 | "description": "", 599 | "builtinExternal": true 600 | }, 601 | { 602 | "__docId__": 43, 603 | "kind": "external", 604 | "name": "Set", 605 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set", 606 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 607 | "static": true, 608 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Set", 609 | "access": null, 610 | "description": "", 611 | "builtinExternal": true 612 | }, 613 | { 614 | "__docId__": 44, 615 | "kind": "external", 616 | "name": "WeakMap", 617 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap", 618 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 619 | "static": true, 620 | "longname": "BuiltinExternal/ECMAScriptExternal.js~WeakMap", 621 | "access": null, 622 | "description": "", 623 | "builtinExternal": true 624 | }, 625 | { 626 | "__docId__": 45, 627 | "kind": "external", 628 | "name": "WeakSet", 629 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet", 630 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 631 | "static": true, 632 | "longname": "BuiltinExternal/ECMAScriptExternal.js~WeakSet", 633 | "access": null, 634 | "description": "", 635 | "builtinExternal": true 636 | }, 637 | { 638 | "__docId__": 46, 639 | "kind": "external", 640 | "name": "ArrayBuffer", 641 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer", 642 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 643 | "static": true, 644 | "longname": "BuiltinExternal/ECMAScriptExternal.js~ArrayBuffer", 645 | "access": null, 646 | "description": "", 647 | "builtinExternal": true 648 | }, 649 | { 650 | "__docId__": 47, 651 | "kind": "external", 652 | "name": "DataView", 653 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView", 654 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 655 | "static": true, 656 | "longname": "BuiltinExternal/ECMAScriptExternal.js~DataView", 657 | "access": null, 658 | "description": "", 659 | "builtinExternal": true 660 | }, 661 | { 662 | "__docId__": 48, 663 | "kind": "external", 664 | "name": "JSON", 665 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON", 666 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 667 | "static": true, 668 | "longname": "BuiltinExternal/ECMAScriptExternal.js~JSON", 669 | "access": null, 670 | "description": "", 671 | "builtinExternal": true 672 | }, 673 | { 674 | "__docId__": 49, 675 | "kind": "external", 676 | "name": "Promise", 677 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise", 678 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 679 | "static": true, 680 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Promise", 681 | "access": null, 682 | "description": "", 683 | "builtinExternal": true 684 | }, 685 | { 686 | "__docId__": 50, 687 | "kind": "external", 688 | "name": "Generator", 689 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator", 690 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 691 | "static": true, 692 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Generator", 693 | "access": null, 694 | "description": "", 695 | "builtinExternal": true 696 | }, 697 | { 698 | "__docId__": 51, 699 | "kind": "external", 700 | "name": "GeneratorFunction", 701 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction", 702 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 703 | "static": true, 704 | "longname": "BuiltinExternal/ECMAScriptExternal.js~GeneratorFunction", 705 | "access": null, 706 | "description": "", 707 | "builtinExternal": true 708 | }, 709 | { 710 | "__docId__": 52, 711 | "kind": "external", 712 | "name": "Reflect", 713 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect", 714 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 715 | "static": true, 716 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Reflect", 717 | "access": null, 718 | "description": "", 719 | "builtinExternal": true 720 | }, 721 | { 722 | "__docId__": 53, 723 | "kind": "external", 724 | "name": "Proxy", 725 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy", 726 | "memberof": "BuiltinExternal/ECMAScriptExternal.js", 727 | "static": true, 728 | "longname": "BuiltinExternal/ECMAScriptExternal.js~Proxy", 729 | "access": null, 730 | "description": "", 731 | "lineNumber": 193, 732 | "builtinExternal": true 733 | }, 734 | { 735 | "__docId__": 55, 736 | "kind": "external", 737 | "name": "CanvasRenderingContext2D", 738 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D", 739 | "memberof": "BuiltinExternal/WebAPIExternal.js", 740 | "static": true, 741 | "longname": "BuiltinExternal/WebAPIExternal.js~CanvasRenderingContext2D", 742 | "access": null, 743 | "description": "", 744 | "builtinExternal": true 745 | }, 746 | { 747 | "__docId__": 56, 748 | "kind": "external", 749 | "name": "DocumentFragment", 750 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment", 751 | "memberof": "BuiltinExternal/WebAPIExternal.js", 752 | "static": true, 753 | "longname": "BuiltinExternal/WebAPIExternal.js~DocumentFragment", 754 | "access": null, 755 | "description": "", 756 | "builtinExternal": true 757 | }, 758 | { 759 | "__docId__": 57, 760 | "kind": "external", 761 | "name": "Element", 762 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Element", 763 | "memberof": "BuiltinExternal/WebAPIExternal.js", 764 | "static": true, 765 | "longname": "BuiltinExternal/WebAPIExternal.js~Element", 766 | "access": null, 767 | "description": "", 768 | "builtinExternal": true 769 | }, 770 | { 771 | "__docId__": 58, 772 | "kind": "external", 773 | "name": "Event", 774 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Event", 775 | "memberof": "BuiltinExternal/WebAPIExternal.js", 776 | "static": true, 777 | "longname": "BuiltinExternal/WebAPIExternal.js~Event", 778 | "access": null, 779 | "description": "", 780 | "builtinExternal": true 781 | }, 782 | { 783 | "__docId__": 59, 784 | "kind": "external", 785 | "name": "Node", 786 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/Node", 787 | "memberof": "BuiltinExternal/WebAPIExternal.js", 788 | "static": true, 789 | "longname": "BuiltinExternal/WebAPIExternal.js~Node", 790 | "access": null, 791 | "description": "", 792 | "builtinExternal": true 793 | }, 794 | { 795 | "__docId__": 60, 796 | "kind": "external", 797 | "name": "NodeList", 798 | "externalLink": "https://developer.mozilla.org/en-US/docs/Web/API/NodeList", 799 | "memberof": "BuiltinExternal/WebAPIExternal.js", 800 | "static": true, 801 | "longname": "BuiltinExternal/WebAPIExternal.js~NodeList", 802 | "access": null, 803 | "description": "", 804 | "builtinExternal": true 805 | }, 806 | { 807 | "__docId__": 61, 808 | "kind": "external", 809 | "name": "XMLHttpRequest", 810 | "externalLink": "https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest", 811 | "memberof": "BuiltinExternal/WebAPIExternal.js", 812 | "static": true, 813 | "longname": "BuiltinExternal/WebAPIExternal.js~XMLHttpRequest", 814 | "access": null, 815 | "description": "", 816 | "builtinExternal": true 817 | }, 818 | { 819 | "__docId__": 62, 820 | "kind": "external", 821 | "name": "AudioContext", 822 | "externalLink": "https://developer.mozilla.org/en/docs/Web/API/AudioContext", 823 | "memberof": "BuiltinExternal/WebAPIExternal.js", 824 | "static": true, 825 | "longname": "BuiltinExternal/WebAPIExternal.js~AudioContext", 826 | "access": null, 827 | "description": "", 828 | "lineNumber": 34, 829 | "builtinExternal": true 830 | } 831 | ] --------------------------------------------------------------------------------