Compare commits
No commits in common. "main-chapril-rebranding" and "weblate-0.1" have entirely different histories.
main-chapr
...
weblate-0.
270
.eslintrc.json
270
.eslintrc.json
@ -1,270 +0,0 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module",
|
||||
"allowImportExportEverywhere": true
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"jasmine": true,
|
||||
"es6": true
|
||||
},
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"globals": {
|
||||
"Uint8Array": true,
|
||||
"Promise": true,
|
||||
"define": true,
|
||||
"require": true,
|
||||
"sinon": true,
|
||||
"window": true
|
||||
},
|
||||
"rules": {
|
||||
"accessor-pairs": "error",
|
||||
"array-bracket-spacing": "off",
|
||||
"array-callback-return": "error",
|
||||
"arrow-body-style": "off",
|
||||
"arrow-parens": "off",
|
||||
"arrow-spacing": "error",
|
||||
"block-scoped-var": "off",
|
||||
"block-spacing": "off",
|
||||
"brace-style": "off",
|
||||
"callback-return": "off",
|
||||
"camelcase": "off",
|
||||
"capitalized-comments": "off",
|
||||
"class-methods-use-this": "error",
|
||||
"comma-dangle": "off",
|
||||
"comma-spacing": "off",
|
||||
"comma-style": "off",
|
||||
"complexity": "off",
|
||||
"computed-property-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"consistent-return": "off",
|
||||
"consistent-this": "off",
|
||||
"curly": "off",
|
||||
"default-case": "off",
|
||||
"dot-location": [
|
||||
"error",
|
||||
"property"
|
||||
],
|
||||
"dot-notation": [
|
||||
"off",
|
||||
{
|
||||
"allowKeywords": true
|
||||
}
|
||||
],
|
||||
"eol-last": "error",
|
||||
"eqeqeq": "off",
|
||||
"func-call-spacing": "off",
|
||||
"no-spaced-func": "off",
|
||||
"no-redeclare": "off",
|
||||
"func-name-matching": "error",
|
||||
"func-names": "off",
|
||||
"func-style": "off",
|
||||
"generator-star-spacing": "error",
|
||||
"global-require": "off",
|
||||
"guard-for-in": "error",
|
||||
"handle-callback-err": "error",
|
||||
"id-blacklist": "error",
|
||||
"id-length": "off",
|
||||
"id-match": "error",
|
||||
"indent": "off",
|
||||
"init-declarations": "off",
|
||||
"jsx-quotes": "error",
|
||||
"key-spacing": "off",
|
||||
"keyword-spacing": "off",
|
||||
"line-comment-position": "off",
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"lines-around-comment": "off",
|
||||
"lines-around-directive": "off",
|
||||
"max-depth": "error",
|
||||
"max-len": "off",
|
||||
"max-lines": "off",
|
||||
"max-nested-callbacks": "off",
|
||||
"max-params": "off",
|
||||
"max-statements": "off",
|
||||
"max-statements-per-line": "off",
|
||||
"multiline-ternary": "off",
|
||||
"new-parens": "error",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"newline-per-chained-call": "off",
|
||||
"no-alert": "off",
|
||||
"no-array-constructor": "error",
|
||||
"no-await-in-loop": "off",
|
||||
"no-bitwise": "off",
|
||||
"no-caller": "error",
|
||||
"no-console": "off",
|
||||
"no-catch-shadow": "off",
|
||||
"no-cond-assign": [
|
||||
"off",
|
||||
"except-parens"
|
||||
],
|
||||
"no-confusing-arrow": "off",
|
||||
"no-continue": "off",
|
||||
"no-div-regex": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-else-return": "off",
|
||||
"no-empty-function": "off",
|
||||
"no-eq-null": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "off",
|
||||
"no-extra-bind": "off",
|
||||
"no-extra-label": "error",
|
||||
"no-extra-parens": "off",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implicit-globals": "off",
|
||||
"no-implied-eval": "error",
|
||||
"no-inline-comments": "off",
|
||||
"no-inner-declarations": [
|
||||
"error",
|
||||
"functions"
|
||||
],
|
||||
"no-invalid-this": "off",
|
||||
"no-iterator": "error",
|
||||
"no-label-var": "error",
|
||||
"no-labels": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-lonely-if": "off",
|
||||
"no-loop-func": "error",
|
||||
"no-magic-numbers": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-mixed-requires": "error",
|
||||
"no-multi-assign": "off",
|
||||
"no-multi-spaces": "off",
|
||||
"no-multi-str": "error",
|
||||
"no-multiple-empty-lines": "error",
|
||||
"no-native-reassign": "error",
|
||||
"no-negated-condition": "off",
|
||||
"no-negated-in-lhs": "error",
|
||||
"no-nested-ternary": "off",
|
||||
"no-new": "off",
|
||||
"no-new-func": "error",
|
||||
"no-new-object": "error",
|
||||
"no-new-require": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-param-reassign": "off",
|
||||
"no-path-concat": "error",
|
||||
"no-plusplus": "off",
|
||||
"no-process-env": "off",
|
||||
"no-process-exit": "error",
|
||||
"no-proto": "error",
|
||||
"no-prototype-builtins": "error",
|
||||
"no-restricted-globals": "error",
|
||||
"no-restricted-imports": "error",
|
||||
"no-restricted-modules": "error",
|
||||
"no-restricted-properties": "error",
|
||||
"no-restricted-syntax": "error",
|
||||
"no-return-assign": "error",
|
||||
"no-return-await": "error",
|
||||
"no-script-url": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-sync": "error",
|
||||
"no-tabs": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-ternary": "off",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "off",
|
||||
"no-undef-init": "error",
|
||||
"no-undefined": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": "off",
|
||||
"no-unused-vars": "error",
|
||||
"no-unused-expressions": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-catch": "off",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-concat": "off",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-escape": "off",
|
||||
"no-useless-rename": "error",
|
||||
"no-useless-return": "off",
|
||||
"no-var": "off",
|
||||
"no-void": "error",
|
||||
"no-warning-comments": "off",
|
||||
"no-whitespace-before-property": "error",
|
||||
"no-with": "error",
|
||||
"object-curly-newline": "off",
|
||||
"object-curly-spacing": "off",
|
||||
"object-property-newline": [
|
||||
"off",
|
||||
{
|
||||
"allowMultiplePropertiesPerLine": true
|
||||
}
|
||||
],
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"one-var-declaration-per-line": "off",
|
||||
"operator-assignment": "off",
|
||||
"operator-linebreak": "off",
|
||||
"padded-blocks": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-const": "error",
|
||||
"prefer-destructuring": [
|
||||
"error",
|
||||
{
|
||||
"array": false,
|
||||
"object": false
|
||||
}
|
||||
],
|
||||
"prefer-numeric-literals": "error",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-template": "off",
|
||||
"quote-props": "off",
|
||||
"quotes": "off",
|
||||
"radix": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"require-atomic-updates": "off",
|
||||
"require-await": "error",
|
||||
"require-jsdoc": "off",
|
||||
"rest-spread-spacing": "error",
|
||||
"semi": "off",
|
||||
"semi-spacing": "off",
|
||||
"sort-imports": "off",
|
||||
"sort-keys": "off",
|
||||
"sort-vars": "off",
|
||||
"space-before-blocks": "off",
|
||||
"space-before-function-paren": "off",
|
||||
"space-in-parens": "off",
|
||||
"space-infix-ops": "off",
|
||||
"space-unary-ops": "off",
|
||||
"spaced-comment": "off",
|
||||
"strict": "off",
|
||||
"symbol-description": "error",
|
||||
"template-curly-spacing": "off",
|
||||
"unicode-bom": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"valid-jsdoc": "off",
|
||||
"vars-on-top": "off",
|
||||
"wrap-iife": [
|
||||
"error",
|
||||
"any"
|
||||
],
|
||||
"wrap-regex": "error",
|
||||
"yield-star-spacing": "error",
|
||||
"yoda": "off"
|
||||
}
|
||||
}
|
28
.github/CONTRIBUTING.md
vendored
28
.github/CONTRIBUTING.md
vendored
@ -1,28 +0,0 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
Thanks for contributing to [Converse.js](https://conversejs.org)
|
||||
|
||||
## Support questions
|
||||
|
||||
The Github issue tracker is used for bug reports and feature requests, not for general tech support.
|
||||
|
||||
For support, you can join our [XMPP webchat](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org).
|
||||
Instead of the webchat, you can also open the room in your XMPP client, [click here](xmpp://discuss@conference.conversejs.org?join).
|
||||
|
||||
You can also ask questions on [StackOverflow](https://stackoverflow.com/questions/tagged/converse.js)
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Please follow the usual Github workflow. Create a fork of this repository, make your changes and then submit a pull request.
|
||||
|
||||
### Before submitting a pull request
|
||||
|
||||
Please read the [style guide](https://conversejs.org/docs/html/style_guide.html) and make sure that your code follows it.
|
||||
|
||||
### Add tests for your bugfix or feature
|
||||
|
||||
Add a test for any bug fixed or feature added.
|
||||
|
||||
Tests can be found in various `./tests` folders in the Converse source code.
|
||||
|
||||
To run the tests, you can run `make check` on Linux and Mac, or `./node_modules/bin/karma start karma.conf` on Windows.
|
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@ -1,4 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: jcbrand
|
||||
liberapay: jcbrand
|
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Environment (please complete the following information):**
|
||||
- Desktop or Mobile?
|
||||
- Browser [e.g. Chrome, Firefox]
|
||||
- Converse.js version [e.g. 4.2.0]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,10 +0,0 @@
|
||||
Thanks for making a pull request to converse.js!
|
||||
|
||||
Before submitting your request, please make sure the following conditions are met:
|
||||
|
||||
- [ ] Add a changelog entry for your change in `CHANGES.md`
|
||||
- [ ] When adding a configuration variable, please make sure to
|
||||
document it in `docs/source/configuration.rst`
|
||||
- [ ] Please add a test for your change. Tests can be run in the commandline
|
||||
with `make check` or you can run them in the browser by running `make serve`
|
||||
and then opening `http://localhost:8000/tests.html`.
|
2
.github/codeql-config.yml
vendored
2
.github/codeql-config.yml
vendored
@ -1,2 +0,0 @@
|
||||
paths-ignore:
|
||||
- '**/tests/*.js'
|
61
.github/dependabot.yml
vendored
61
.github/dependabot.yml
vendored
@ -1,61 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: mini-css-extract-plugin
|
||||
versions:
|
||||
- 1.3.5
|
||||
- 1.3.6
|
||||
- 1.3.7
|
||||
- 1.3.8
|
||||
- 1.3.9
|
||||
- 1.4.0
|
||||
- 1.4.1
|
||||
- 1.5.0
|
||||
- dependency-name: css-loader
|
||||
versions:
|
||||
- 5.0.1
|
||||
- 5.0.2
|
||||
- 5.1.0
|
||||
- 5.1.1
|
||||
- 5.1.2
|
||||
- 5.1.3
|
||||
- 5.2.0
|
||||
- 5.2.1
|
||||
- dependency-name: y18n
|
||||
versions:
|
||||
- 4.0.2
|
||||
- dependency-name: sinon
|
||||
versions:
|
||||
- 10.0.0
|
||||
- 9.2.4
|
||||
- dependency-name: bootstrap
|
||||
versions:
|
||||
- 4.6.0
|
||||
- dependency-name: "@babel/plugin-proposal-nullish-coalescing-operator"
|
||||
versions:
|
||||
- 7.12.1
|
||||
- 7.12.13
|
||||
- 7.13.0
|
||||
- 7.13.8
|
||||
- dependency-name: webpack-cli
|
||||
versions:
|
||||
- 4.4.0
|
||||
- 4.5.0
|
||||
- dependency-name: webpack-merge
|
||||
versions:
|
||||
- 5.7.3
|
||||
- dependency-name: xmldom
|
||||
versions:
|
||||
- 0.5.0
|
||||
- dependency-name: urijs
|
||||
versions:
|
||||
- 1.19.4
|
||||
- 1.19.6
|
||||
- dependency-name: sass-loader
|
||||
versions:
|
||||
- 10.1.1
|
43
.github/workflows/codeql.yml
vendored
43
.github/workflows/codeql.yml
vendored
@ -1,43 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: "11 18 * * 6"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ javascript ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
config-file: ./.github/codeql-config.yml
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
if: ${{ matrix.language == 'javascript' }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
34
.github/workflows/karma-tests.yml
vendored
34
.github/workflows/karma-tests.yml
vendored
@ -1,34 +0,0 @@
|
||||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: CI Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISPLAY: :99.0
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
- name: Run Karma tests
|
||||
uses: GabrielBB/xvfb-action@v1
|
||||
with:
|
||||
run: make check ARGS=--single-run
|
68
.gitignore
vendored
68
.gitignore
vendored
@ -1,66 +1,4 @@
|
||||
# Distribution directory
|
||||
dist
|
||||
|
||||
# conversejs/media repo checkout
|
||||
media
|
||||
|
||||
# Editor fluff
|
||||
*~
|
||||
.sw?
|
||||
*.mo
|
||||
*.kpf
|
||||
.*.sw?
|
||||
|
||||
.hg/
|
||||
.bzr/
|
||||
.svn/
|
||||
.project
|
||||
.pydevproject
|
||||
.idea
|
||||
.su?
|
||||
.sass-cache
|
||||
pip-selfcheck.json
|
||||
|
||||
3rdparty/libsignal-protocol-javascript/
|
||||
*.map
|
||||
|
||||
locale.zip
|
||||
sounds.zip
|
||||
|
||||
analytics.js
|
||||
|
||||
# virtualenv/python/buildout
|
||||
.*.cfg
|
||||
eggs
|
||||
.Python
|
||||
build
|
||||
share
|
||||
parts
|
||||
*.pyc
|
||||
*.egg-info
|
||||
lib
|
||||
lib64
|
||||
include
|
||||
bin
|
||||
develop-eggs
|
||||
pyvenv.cfg
|
||||
|
||||
converse-logs/*.html
|
||||
|
||||
Backbone.Overview
|
||||
tags
|
||||
transpile
|
||||
|
||||
# Sphinx
|
||||
docs/html
|
||||
docs/doctrees
|
||||
|
||||
# Node.js
|
||||
node_modules
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Builds
|
||||
.sv?
|
||||
/vendor/
|
||||
*.swp
|
||||
repos/
|
||||
*.mo
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"quoteProps": "preserve",
|
||||
"singleQuote": true,
|
||||
"spaceBeforeFunctionParen": true,
|
||||
"tabWidth": 4
|
||||
}
|
36541
3rdparty/libsignal-protocol.js
vendored
36541
3rdparty/libsignal-protocol.js
vendored
File diff suppressed because one or more lines are too long
1
3rdparty/libsignal-protocol.min.js
vendored
1
3rdparty/libsignal-protocol.min.js
vendored
File diff suppressed because one or more lines are too long
1857
CHANGES.md
1857
CHANGES.md
File diff suppressed because it is too large
Load Diff
674
COPYING
Normal file
674
COPYING
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
12
COPYRIGHT
12
COPYRIGHT
@ -1,12 +0,0 @@
|
||||
/** Converse.js
|
||||
*
|
||||
* An XMPP chat client that runs in the browser.
|
||||
*
|
||||
* Version: 10.1.6
|
||||
*
|
||||
* Copyright: JC Brand 2013-2018
|
||||
* Except for 3rd party dependencies.
|
||||
* Please refer to the unminified version of this file for details.
|
||||
*
|
||||
* You can download it at: https://github.com/conversejs/converse.js/releases
|
||||
*/
|
6
ChangeLog
Normal file
6
ChangeLog
Normal file
@ -0,0 +1,6 @@
|
||||
weblate 0.1
|
||||
-----------
|
||||
|
||||
Relased on February 6th 2012.
|
||||
|
||||
Initial release.
|
373
LICENSE
373
LICENSE
@ -1,373 +0,0 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
269
Makefile
269
Makefile
@ -1,269 +0,0 @@
|
||||
# You can set these variables from the command line.
|
||||
BOOTSTRAP = ./node_modules/
|
||||
BUILDDIR = ./docs
|
||||
KARMA ?= ./node_modules/.bin/karma
|
||||
CLEANCSS ?= ./node_modules/clean-css-cli/bin/cleancss
|
||||
HTTPSERVE ?= ./node_modules/.bin/http-server
|
||||
HTTPSERVE_PORT ?= 8000
|
||||
INKSCAPE ?= inkscape
|
||||
INSTALL ?= install
|
||||
JSDOC ?= ./node_modules/.bin/jsdoc
|
||||
OXIPNG ?= oxipng
|
||||
PAPER =
|
||||
RJS ?= ./node_modules/.bin/r.js
|
||||
NPX ?= ./node_modules/.bin/npx
|
||||
SASS ?= ./node_modules/.bin/sass
|
||||
SED ?= sed
|
||||
SPHINXBUILD ?= ./bin/sphinx-build
|
||||
SPHINXOPTS =
|
||||
XGETTEXT = xgettext
|
||||
|
||||
|
||||
# Internal variables.
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ./docs/source
|
||||
VERSION_FORMAT = [0-9]+\.[0-9]+\.[0-9]+
|
||||
|
||||
.PHONY: all
|
||||
all: node_modules dist
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of the following:"
|
||||
@echo ""
|
||||
@echo " all Set up dev environment and create all builds"
|
||||
@echo " dist Create minified builds of converse.js and all its dependencies."
|
||||
@echo " clean Remove all NPM packages."
|
||||
@echo " check Run all tests."
|
||||
@echo " dev Set up the development environment and build unminified resources. To force a fresh start, run 'make clean' first."
|
||||
@echo " devserver Set up the development environment and start the webpack dev server."
|
||||
@echo " doc Make standalone HTML files of the documentation."
|
||||
@echo " po Generate gettext PO files for each i18n language."
|
||||
@echo " pot Generate a gettext POT file to be used for translations."
|
||||
@echo " release Prepare a new release of converse.js. E.g. make release VERSION=0.9.5"
|
||||
@echo " serve Serve this directory via a webserver on port 8000."
|
||||
@echo " serve_bg Same as \"serve\", but do it in the background"
|
||||
@echo " node_modules Install NPM dependencies"
|
||||
@echo " watch Watch for changes on JS and scss files and automatically update the generated files."
|
||||
@echo " logo Generate PNG logos of multiple sizes."
|
||||
|
||||
|
||||
########################################################################
|
||||
## Miscellaneous
|
||||
|
||||
.PHONY: serve
|
||||
serve: node_modules dist
|
||||
$(HTTPSERVE) -p $(HTTPSERVE_PORT) -c-1
|
||||
|
||||
.PHONY: serve_bg
|
||||
serve_bg: node_modules
|
||||
$(HTTPSERVE) -p $(HTTPSERVE_PORT) -c-1 -s &
|
||||
|
||||
certs:
|
||||
mkdir certs
|
||||
cd certs && openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out chat.example.org.crt -keyout chat.example.org.key
|
||||
|
||||
########################################################################
|
||||
## Translation machinery
|
||||
|
||||
GETTEXT = $(XGETTEXT) --from-code=UTF-8 --language=JavaScript --keyword=__ --keyword=___ --keyword=i18n_ --force-po --output=src/i18n/converse.pot --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=10.1.6 dist/converse-no-dependencies.js -c
|
||||
|
||||
src/i18n/converse.pot: dist/converse-no-dependencies.js
|
||||
$(GETTEXT) 2>&1 > /dev/null; exit $$?;
|
||||
rm dist/converse-no-dependencies.js
|
||||
rm dist/tmp.css
|
||||
|
||||
.PHONY: pot
|
||||
pot: src/i18n/converse.pot
|
||||
|
||||
.PHONY: po
|
||||
po:
|
||||
find ./src/i18n -maxdepth 1 -mindepth 1 -type d -exec msgmerge {}/LC_MESSAGES/converse.po ./src/i18n/converse.pot -U \;
|
||||
|
||||
########################################################################
|
||||
## Release management
|
||||
|
||||
.PHONY: version
|
||||
version:
|
||||
$(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)";/' src/headless/shared/constants.js
|
||||
$(SED) -i '/Version:/s/:.*/: $(VERSION)/' COPYRIGHT
|
||||
$(SED) -i '/Project-Id-Version:/s/:.*/: Converse.js $(VERSION)\n"/' src/i18n/converse.pot
|
||||
$(SED) -i '/"version":/s/:.*/: "$(VERSION)",/' manifest.json
|
||||
$(SED) -i '/"version":/s/:.*/: "$(VERSION)",/' package.json
|
||||
$(SED) -i '/"version":/s/:.*/: "$(VERSION)",/' src/headless/package.json
|
||||
$(SED) -ri 's/--package-version=$(VERSION_FORMAT)/--package-version=$(VERSION)/' Makefile
|
||||
$(SED) -i -e "/version =/s/=.*/= '$(VERSION)'/" -e "/release =/s/=.*/= '$(VERSION)'/" docs/source/conf.py
|
||||
$(SED) -i "s/[Uu]nreleased/`date +%Y-%m-%d`/" CHANGES.md
|
||||
$(SED) -ri 's,cdn.conversejs.org/$(VERSION_FORMAT),cdn.conversejs.org/$(VERSION),' docs/source/quickstart.rst
|
||||
$(SED) -ri 's,cdn.conversejs.org/$(VERSION_FORMAT),cdn.conversejs.org/$(VERSION),' *.html
|
||||
$(SED) -ri 's,cdn.conversejs.org/$(VERSION_FORMAT),cdn.conversejs.org/$(VERSION),' demo/*.html
|
||||
make pot
|
||||
make po
|
||||
make dist
|
||||
|
||||
release-checkout:
|
||||
git clone git@github.com:conversejs/converse.js.git --depth 1 --branch $(BRANCH) release-$(BRANCH)
|
||||
cd release-$(BRANCH) && make dist
|
||||
|
||||
.PHONY: publish
|
||||
publish:
|
||||
make release-checkout
|
||||
cd release-$(BRANCH) && npm pack && npm publish
|
||||
cd release-$(BRANCH)/src/headless && npm pack && npm publish
|
||||
find ./release-$(BRANCH)/ -name "converse.js-*.tgz" -exec mv {} . \;
|
||||
find ./release-$(BRANCH)/src/headless -name "converse-headless-*.tgz" -exec mv {} . \;
|
||||
rm -rf release-$(BRANCH)
|
||||
|
||||
.PHONY: postrelease
|
||||
postrelease:
|
||||
$(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)dev";/' src/headless/shared/constants.js
|
||||
|
||||
.PHONY: deploy
|
||||
deploy:
|
||||
git clone --branch v$(VERSION) git@github.com:conversejs/converse.js.git --depth 1 $(VERSION)
|
||||
cd $(VERSION) && make node && ASSET_PATH=https://cdn.conversejs.org/$(VERSION)/dist/ make dist && make doc
|
||||
cd .. && git pull && make node && ASSET_PATH=https://cdn.conversejs.org/dist/ make dist && make doc
|
||||
|
||||
########################################################################
|
||||
## Install dependencies
|
||||
|
||||
${NVM_DIR}/nvm.sh:
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
|
||||
source ~/.bashrc
|
||||
|
||||
.PHONY: nvm
|
||||
nvm: ${NVM_DIR}/nvm.sh
|
||||
|
||||
.PHONY: node
|
||||
node: .nvmrc
|
||||
. $(HOME)/.nvm/nvm.sh && nvm install
|
||||
|
||||
node_modules: package.json src/headless/package.json
|
||||
npm install
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
npm run clean
|
||||
rm -rf lib bin include parts
|
||||
|
||||
.PHONY: dev
|
||||
dev: node_modules
|
||||
npm run dev
|
||||
|
||||
.PHONY: devserver
|
||||
devserver: node_modules
|
||||
npm run serve
|
||||
|
||||
########################################################################
|
||||
## Builds
|
||||
|
||||
dist/converse-no-dependencies.js: src webpack/webpack.common.js webpack/webpack.nodeps.js @converse/headless node_modules
|
||||
npm run nodeps
|
||||
|
||||
dist/converse.js:: node_modules
|
||||
npm run build
|
||||
|
||||
dist/converse.css:: node_modules
|
||||
npm run build
|
||||
|
||||
dist/website.css:: node_modules src/shared/styles/website.scss
|
||||
$(SASS) --load-path=$(BOOTSTRAP) src/shared/styles/website.scss $@
|
||||
|
||||
dist/website.min.css:: node_modules dist/website.css
|
||||
$(CLEANCSS) dist/website.css > $@
|
||||
|
||||
.PHONY: watch
|
||||
watch: node_modules
|
||||
npm run watch
|
||||
|
||||
.PHONY: logo
|
||||
logo: logo/conversejs-transparent16.png \
|
||||
logo/conversejs-transparent19.png \
|
||||
logo/conversejs-transparent48.png \
|
||||
logo/conversejs-transparent128.png \
|
||||
logo/conversejs-transparent512.png \
|
||||
logo/conversejs-filled16.png \
|
||||
logo/conversejs-filled19.png \
|
||||
logo/conversejs-filled48.png \
|
||||
logo/conversejs-filled128.png \
|
||||
logo/conversejs-filled512.png \
|
||||
|
||||
logo/conversejs-transparent%.png:: logo/conversejs-transparent.svg
|
||||
$(INKSCAPE) -e $@ -w $* $<
|
||||
$(OXIPNG) $@
|
||||
|
||||
logo/conversejs-filled%.png:: logo/conversejs-filled.svg
|
||||
$(INKSCAPE) -e $@ -w $* $<
|
||||
$(OXIPNG) $@
|
||||
|
||||
@converse/headless: src/headless
|
||||
|
||||
src/headless/dist/converse-headless.js: src webpack/webpack.common.js node_modules @converse/headless
|
||||
npm run headless-dev
|
||||
|
||||
src/headless/dist/converse-headless.min.js: src webpack/webpack.common.js node_modules @converse/headless
|
||||
npm run headless
|
||||
|
||||
dist:: node_modules src/* | dist/website.css dist/website.min.css
|
||||
npm run headless
|
||||
# Ideally this should just be `npm run build`.
|
||||
# The additional steps are necessary to properly generate JSON chunk files
|
||||
# from the .po files. The nodeps config uses preset-env with IE11.
|
||||
# Somehow this is necessary.
|
||||
npm run nodeps
|
||||
$(eval TMPD := $(shell mktemp -d))
|
||||
mv dist/locales $(TMPD) && \
|
||||
npm run build && \
|
||||
mv $(TMPD)/locales/*-po.js dist/locales/ && \
|
||||
rm -rf $(TMPD)
|
||||
|
||||
.PHONY: install
|
||||
install:: dist
|
||||
|
||||
.PHONY: cdn
|
||||
cdn:: node_modules
|
||||
npm run cdn
|
||||
|
||||
.PHONY: types
|
||||
types:: node_modules
|
||||
npm run types
|
||||
|
||||
########################################################################
|
||||
## Tests
|
||||
|
||||
.PHONY: eslint
|
||||
eslint: node_modules
|
||||
npm run lint
|
||||
|
||||
.PHONY: check
|
||||
check: eslint | dist/converse.js dist/converse.css
|
||||
npm run test -- $(ARGS)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
npm run test -- $(ARGS)
|
||||
|
||||
########################################################################
|
||||
## Documentation
|
||||
|
||||
./bin/activate:
|
||||
python3 -m venv .
|
||||
|
||||
.PHONY: docsdev
|
||||
docsdev: ./bin/activate requirements.txt
|
||||
./bin/pip install --upgrade pip==21.3.1
|
||||
./bin/pip install -r requirements.txt
|
||||
|
||||
.PHONY: html
|
||||
html: doc
|
||||
|
||||
.PHONY: doc
|
||||
doc: node_modules docsdev apidoc
|
||||
rm -rf $(BUILDDIR)/html
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
make apidoc
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
PHONY: apidoc
|
||||
apidoc:
|
||||
find ./src -type d -name node_modules -prune -false -o -name "*.js" | xargs $(JSDOC) --private --readme docs/source/jsdoc_intro.md -c docs/source/conf.json -d docs/html/api
|
@ -1,17 +0,0 @@
|
||||
# Construire une version Chapril de ConverseJS
|
||||
|
||||
```
|
||||
cd .../conversejs
|
||||
# La première fois, installer nvm (attention, ça va modifier le .bashrc, entre autres choses)
|
||||
make nvm
|
||||
|
||||
export V=7.0.4
|
||||
git rebase v${V?}
|
||||
# [... Résoudre les conflits]
|
||||
git checkout -b v${V?}-chapril
|
||||
nvm install
|
||||
make dist
|
||||
# [... Tester les livrables présents dans dist/, et si tout est ok :]
|
||||
make version VERSION=${V?}-chapril
|
||||
rsync -av dist/ chapril-xmpp:/var/www/xmpp.chapril.org/public_html/dist-custom-chapril-${V?}/
|
||||
```
|
188
README.md
188
README.md
@ -1,188 +0,0 @@
|
||||
<h2 align="center">
|
||||
<a href="https://conversejs.org" target="_blank" rel="noopener">
|
||||
<img alt="Converse.js" src="https://github.com/conversejs/converse.js/blob/master/logo/readme.png" width="480">
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
|
||||
[![XMPP Chat](https://conference.conversejs.org/muc_badge/discuss@conference.conversejs.org)](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org)
|
||||
[![CI Tests](https://github.com/conversejs/converse.js/actions/workflows/karma-tests.yml/badge.svg)](https://github.com/conversejs/converse.js/actions/workflows/karma-tests.yml)
|
||||
[![Bountysource bounties](https://img.shields.io/bountysource/team/converse.js/activity.svg?maxAge=2592000)](https://www.bountysource.com/teams/converse.js/issues?tracker_ids=194169)
|
||||
[![Translation status](https://hosted.weblate.org/widgets/conversejs/-/svg-badge.svg)](https://hosted.weblate.org/engage/conversejs/?utm_source=widget)
|
||||
|
||||
[Converse](https://conversejs.org) is a web based [XMPP/Jabber](https://xmpp.org) chat client.
|
||||
|
||||
You can either use it as a webchat app, or you can integrate it into your own website.
|
||||
|
||||
It's 100% client-side JavaScript, HTML and CSS and the only backend required
|
||||
is a modern XMPP server.
|
||||
|
||||
Please support this project via [Patreon](https://www.patreon.com/jcbrand) or [Liberapay](https://liberapay.com/jcbrand)
|
||||
|
||||
## Demo
|
||||
|
||||
Converse is hosted and can be used at [https://conversejs.org](https://conversejs.org).
|
||||
|
||||
A demo showing anonymous login is available at [https://conversejs.org/demo/anonymous.html](https://conversejs.org/demo/anonymous.html)
|
||||
and a demo which shows how you can embed a single chat room into a page is
|
||||
avialable at [https://conversejs.org/demo/embedded.html](https://conversejs.org/demo/embedded.html).
|
||||
|
||||
## Documentation
|
||||
|
||||
The developer/integrator documentation can be found at [https://conversejs.org/docs/html](https://conversejs.org/docs/html).
|
||||
|
||||
You'll probably want to begin with the [quickstart guide](https://conversejs.org/docs/html/quickstart.html),
|
||||
which shows you how to use the CDN (content delivery network) to quickly get a demo up and running.
|
||||
|
||||
## Converse modes
|
||||
|
||||
### Overlay
|
||||
|
||||
In overlay mode, Converse appears overlayed chats on top of the website.
|
||||
|
||||
![Screenshot of Converse in overlay mode](https://conversejs.org/screenshots/Converse-overlayed.png)
|
||||
|
||||
### Fullpage
|
||||
|
||||
In fullpage mode, Converse behaves like a single-page app that covers the whole browser viewport.
|
||||
|
||||
![Screenshot of Converse 9.0.0 in fullpage mode](https://conversejs.org/screenshots/Converse-fullscreen.png)
|
||||
|
||||
### Dark mode
|
||||
|
||||
![Screenshot of Converse 9.1.0 with a dark theme](https://conversejs.org/screenshots/Converse-Dracula-Theme.png)
|
||||
|
||||
### Embedded
|
||||
|
||||
In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
|
||||
![Screenshot of Converse in embedded mode](https://conversejs.org/screenshots/Converse-embedded.png)
|
||||
|
||||
## Features
|
||||
- Available as overlayed chat boxes or as a fullscreen application. See [inverse.chat](https://inverse.chat) for the fullscreen version.
|
||||
- Custom status messages
|
||||
- Desktop notifications
|
||||
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://conversejs.github.io/pluggable.js/)
|
||||
- Chat statuses (online, busy, away, offline)
|
||||
- Anonymous logins, see the [anonymous login demo](https://conversejs.org/demo/anonymous.html)
|
||||
- URL Previews (requires server support, for example [mod_ogp](https://modules.prosody.im/mod_ogp.html)
|
||||
- Translated into over 30 languages
|
||||
|
||||
### Supported XMPP Extensions
|
||||
|
||||
- [RFC-7395](https://tools.ietf.org/html/rfc7395) XMPP Subprotocol support for WebSocket
|
||||
- [XEP-0004](https://xmpp.org/extensions/xep-0004.html) Data Forms
|
||||
- [XEP-0030](https://xmpp.org/extensions/xep-0030.html) Service discovery
|
||||
- [XEP-0045](https://xmpp.org/extensions/xep-0045.html) Multi-user chat rooms
|
||||
- [XEP-0048](https://xmpp.org/extensions/xep-0048.html) Bookmarks
|
||||
- [XEP-0050](https://xmpp.org/extensions/xep-0050.html) Ad-Hoc Commands
|
||||
- [XEP-0054](https://xmpp.org/extensions/xep-0054.html) VCard-temp
|
||||
- [XEP-0059](https://xmpp.org/extensions/xep-0059.html) Result Set Management
|
||||
- [XEP-0060](https://xmpp.org/extensions/xep-0060.html) Publish-Subscribe (limited support)
|
||||
- [XEP-0066](https://xmpp.org/extensions/xep-0066.html) Out of Band Data
|
||||
- [XEP-0077](https://xmpp.org/extensions/xep-0077.html) In-band registration
|
||||
- [XEP-0085](https://xmpp.org/extensions/xep-0085.html) Chat State Notifications
|
||||
- [XEP-0115](https://xmpp.org/extensions/xep-0115.html) Entity Capabilities
|
||||
- [XEP-0124](https://xmpp.org/extensions/xep-0124.html) Bidirectional-streams Over Synchronous HTTP (BOSH)
|
||||
- [XEP-0144](https://xmpp.org/extensions/xep-0144.html) Roster item exchange
|
||||
- [XEP-0156](https://xmpp.org/extensions/xep-0156.html) Discovering Alternative XMPP Connection Methods
|
||||
- [XEP-0163](https://xmpp.org/extensions/xep-0163.html) Personal Eventing Protocol (limited support)
|
||||
- [XEP-0184](https://xmpp.org/extensions/xep-0184.html) Message Receipt
|
||||
- [XEP-0198](https://xmpp.org/extensions/xep-0198.html) Stream Management
|
||||
- [XEP-0199](https://xmpp.org/extensions/xep-0199.html) XMPP Ping
|
||||
- [XEP-0203](https://xmpp.org/extensions/xep-0203.html) Delayed Delivery
|
||||
- [XEP-0206](https://xmpp.org/extensions/xep-0206.html) XMPP Over BOSH
|
||||
- [XEP-0245](https://xmpp.org/extensions/xep-0245.html) The /me Command
|
||||
- [XEP-0249](https://xmpp.org/extensions/xep-0249.html) Direct MUC Invitations
|
||||
- [XEP-0280](https://xmpp.org/extensions/xep-0280.html) Message Carbons
|
||||
- [XEP-0297](https://xmpp.org/extensions/xep-0297.html) Stanza Forwarding (limited support)
|
||||
- [XEP-0308](https://xmpp.org/extensions/xep-0308.html) Last Message Correction
|
||||
- [XEP-0313](https://xmpp.org/extensions/xep-0313.html) Message Archive Management
|
||||
- [XEP-0316](https://xmpp.org/extensions/xep-0316.html) MUC Eventing protocol (limited support)
|
||||
- [XEP-0317](https://xmpp.org/extensions/xep-0317.html) Hats (limited support)
|
||||
- [XEP-0333](https://xmpp.org/extensions/xep-0333.html) Chat Markers (limited support)
|
||||
- [XEP-0352](https://xmpp.org/extensions/xep-0352.html) Client State Indication
|
||||
- [XEP-0357](https://xmpp.org/extensions/xep-0357.html) Push Notifications
|
||||
- [XEP-0359](https://xmpp.org/extensions/xep-0359.html) Unique and Stable Stanza IDs
|
||||
- [XEP-0363](https://xmpp.org/extensions/xep-0363.html) HTTP File Upload
|
||||
- [XEP-0372](https://xmpp.org/extensions/xep-0372.html) References
|
||||
- [XEP-0382](https://xmpp.org/extensions/xep-0382.html) Spoiler messages
|
||||
- [XEP-0384](https://xmpp.org/extensions/xep-0384.html) OMEMO Encryption
|
||||
- [XEP-0393](https://xmpp.org/extensions/xep-0393.html) Message styling
|
||||
- [XEP-0422](https://xmpp.org/extensions/xep-0422.html) Message Fastening (limited support)
|
||||
- [XEP-0424](https://xmpp.org/extensions/xep-0424.html) Message Retractions
|
||||
- [XEP-0425](https://xmpp.org/extensions/xep-0425.html) Message Moderation
|
||||
- [XEP-0437](https://xmpp.org/extensions/xep-0437.html) Room Activity Indicators
|
||||
- [XEP-0453](https://xmpp.org/extensions/xep-0453.html) DOAP Usage in XMPP
|
||||
- [XEP-0454](https://xmpp.org/extensions/xep-0454.html) OMEMO Media sharing
|
||||
|
||||
## Integration into other servers and frameworks
|
||||
|
||||
### XMPP servers
|
||||
|
||||
- **[Openfire](https://www.igniterealtime.org/projects/openfire/index.jsp)**: [inverse.jar](https://www.igniterealtime.org/projects/openfire/plugins.jsp)
|
||||
- **[Prosody](https://prosody.im/)**: [mod_conversejs](https://modules.prosody.im/mod_conversejs.html)
|
||||
- **[Ejabberd](https://ejabberd.im/)**: [mod-conversejs](https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs)
|
||||
|
||||
### Other
|
||||
|
||||
- **[Alfresco](https://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)
|
||||
- **[Django](https://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
|
||||
- **[Elgg](https://elgg.org)**: [plugin](https://elgg.org/plugins/2997196)
|
||||
- **[Friendica](https://friendi.ca)**: [converse](https://github.com/friendica/friendica-addons/tree/master/xmpp/converse)
|
||||
- **[Patternslib](http://patternslib.com)**: [patterns.converse](https://github.com/jcbrand/patterns.converse)
|
||||
- **[Plone](https://plone.com)**: [collective.converse](https://github.com/collective/collective.converse)
|
||||
- **[Pàdé](https://www.igniterealtime.org/projects/pade/index.jsp)**: [Pàdé](https://www.igniterealtime.org/projects/pade/index.jsp)
|
||||
- **[Roundcube](https://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
|
||||
- **[Ruby on Rails](https://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
|
||||
- **[Tiki Wiki CMS Groupware](https://tiki.org)**: [built-in optional feature](https://doc.tiki.org/XMPP)
|
||||
- **[Wordpress](https://wordpress.org)**: [ConverseJS](https://wordpress.org/plugins/conversejs/)
|
||||
|
||||
|
||||
## Tests
|
||||
|
||||
We use behavior-driven tests written with [jasmine.js](https://jasmine.github.io/).
|
||||
|
||||
Run `make check` to execute all the tests.
|
||||
|
||||
## Licence
|
||||
|
||||
`Converse.js` is released under the [Mozilla Public License (MPL)](https://www.mozilla.org/MPL/2.0/index.txt).
|
||||
|
||||
## Attribution
|
||||
|
||||
Emoji images are courtesy of [Twemoji](https://emojitwo.github.io/).
|
||||
|
||||
## Support
|
||||
|
||||
Issues can be logged on the [Github issue tracker](https://github.com/conversejs/converse.js/issues).
|
||||
|
||||
## Donations
|
||||
|
||||
A heartfelt thanks for everyone who has supported this project over the years.
|
||||
Many people have contributed testing, bugfixes, features and corrections.
|
||||
|
||||
We accept donations via [Patreon](https://www.patreon.com/jcbrand) and [Liberapay](https://liberapay.com/jcbrand).
|
||||
|
||||
## Sponsors
|
||||
|
||||
<p>
|
||||
<a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="BairesDev" src="https://raw.githubusercontent.com/conversejs/media/main/logos/bairesdev-primary.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="Blokt Crypto & Privacy" src="https://raw.githubusercontent.com/conversejs/converse.js/541613d1fea8aef364af00180f60e959162e5e4b/logo/blokt.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="Prime Sound" src="https://raw.githubusercontent.com/conversejs/media/main/logos/primesound.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="KeyCDN" src="https://raw.githubusercontent.com/conversejs/converse.js/541613d1fea8aef364af00180f60e959162e5e4b/logo/keycdn.png" width="200">
|
||||
</a>
|
||||
</p>
|
87
README.rst
Normal file
87
README.rst
Normal file
@ -0,0 +1,87 @@
|
||||
Weblate
|
||||
=======
|
||||
|
||||
Weblate is web based translation tool. It is based on translate-toolkit and
|
||||
heavily uses git backed to store project.
|
||||
|
||||
Project goals
|
||||
-------------
|
||||
|
||||
Minimalistic web based translation with direct commit to git on each
|
||||
translation made. There is no plan in heavy conflict resolution as these
|
||||
should be primarily handled on git side.
|
||||
|
||||
Planned features
|
||||
----------------
|
||||
|
||||
* Easy web based translation
|
||||
* Propagation of translations accross sub-projects (for different branches)
|
||||
* Tight git integration
|
||||
* Usage of Django's admin interface
|
||||
* Upload and automatic merging of po files
|
||||
* Links to source files for context
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Django
|
||||
https://www.djangoproject.com/
|
||||
Translate-toolkit
|
||||
http://translate.sourceforge.net/wiki/toolkit/index
|
||||
GitPython (>= 0.3)
|
||||
http://gitorious.org/projects/git-python/
|
||||
Django-registration
|
||||
https://bitbucket.org/ubernostrum/django-registration/
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install all required components (see above), adjust settings.py and then run
|
||||
./manage.py syncdb to create database structure. Now you should be able to
|
||||
create translation projects using admin interface. You probably also want to
|
||||
run ./manage.py setuplang to get default list of languages.
|
||||
|
||||
As setup of translation project includes fetching Git repositories, you might
|
||||
want to preseed these, repos are stored in path defined by GIT_ROOT in
|
||||
settings.py in <project>/<subproject> directories.
|
||||
|
||||
Management commands
|
||||
-------------------
|
||||
|
||||
The ./manage.py is extended with following commands:
|
||||
|
||||
loadpo
|
||||
Reloads translations from disk (eg. in case you did some updates in Git
|
||||
repository).
|
||||
setuplang
|
||||
Setups list of languages (it has own list and all defined in
|
||||
translate-toolkit).
|
||||
updategit
|
||||
Fetches remote Git repositories and updates internal cache.
|
||||
|
||||
Project name
|
||||
------------
|
||||
|
||||
The project is named as mixture of words web and translate.
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
This tool was written by Michal Čihař <michal@cihar.com>.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright (C) 2012 Michal Čihař <michal@cihar.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
18
RELEASE.md
18
RELEASE.md
@ -1,18 +0,0 @@
|
||||
# Release checklist
|
||||
|
||||
1. Merge weblate translations: https://hosted.weblate.org/projects/conversejs/translations/#repository
|
||||
2. Run `make check` to check that all tests pass.
|
||||
3. Run `make version VERSION=10.1.6`
|
||||
4. Do a `git diff` to check if things look sane.
|
||||
5. Do a quick manual test with the `dist` files (via `index.html`)
|
||||
6. `git commit -am "Release 10.1.6"`
|
||||
7. `git tag -s v10.1.6 -m "Release 10.1.6"`
|
||||
8. `git push && git push origin v10.1.6`
|
||||
9. `make publish BRANCH=v10.1.6`
|
||||
10. Update release page on Github
|
||||
* Upload tar files
|
||||
11. Update https://conversejs.org
|
||||
* `cd /home/conversejs/converse.js`
|
||||
* `make deploy VERSION=10.1.6`
|
||||
12. Update the repository on weblate
|
||||
13. Decide on next release number and run `make postrelease VERSION=10.1.7`
|
8
TODO
Normal file
8
TODO
Normal file
@ -0,0 +1,8 @@
|
||||
Possible features for future releases
|
||||
|
||||
* Auto translate using some online service
|
||||
* Checking of messages
|
||||
* \n at beginning/end
|
||||
* php-format
|
||||
* python-format
|
||||
* Glossary of frequently used term (per project)
|
0
__init__.py
Normal file
0
__init__.py
Normal file
0
accounts/__init__.py
Normal file
0
accounts/__init__.py
Normal file
8
accounts/admin.py
Normal file
8
accounts/admin.py
Normal file
@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from accounts.models import Profile
|
||||
|
||||
class ProfileAdmin(admin.ModelAdmin):
|
||||
search_fields = ['user__username']
|
||||
|
||||
admin.site.register(Profile, ProfileAdmin)
|
||||
|
53
accounts/forms.py
Normal file
53
accounts/forms.py
Normal file
@ -0,0 +1,53 @@
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from accounts.models import Profile
|
||||
from django.contrib.auth.models import User
|
||||
from registration.forms import RegistrationFormUniqueEmail
|
||||
|
||||
class ProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Profile
|
||||
exclude = [
|
||||
'suggested',
|
||||
'translated',
|
||||
]
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
]
|
||||
|
||||
class ContactForm(forms.Form):
|
||||
subject = forms.CharField(label = _('Subject'), required = True)
|
||||
name = forms.CharField(label = _('Your name'), required = True)
|
||||
email = forms.EmailField(label = _('Your email'), required = True)
|
||||
message = forms.CharField(
|
||||
label = _('Message'),
|
||||
required = True,
|
||||
widget = forms.Textarea
|
||||
)
|
||||
|
||||
class RegistrationForm(RegistrationFormUniqueEmail):
|
||||
first_name = forms.CharField(label = _('First name'))
|
||||
last_name = forms.CharField(label = _('Last name'))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super(RegistrationForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['username'].label = _('Username')
|
||||
self.fields['email'].label = _('Email address')
|
||||
self.fields['password1'].label = _('Password')
|
||||
self.fields['password2'].label = _('Password (again)')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
new_user = super(RegistrationForm, self).save(*args, **kwargs)
|
||||
new_user.first_name = self.cleaned_data['first_name']
|
||||
new_user.last_name = self.cleaned_data['last_name']
|
||||
new_user.save()
|
||||
return new_user
|
8
accounts/i18n.py
Normal file
8
accounts/i18n.py
Normal file
@ -0,0 +1,8 @@
|
||||
'''
|
||||
Fake file to translate messages from django-registration.
|
||||
'''
|
||||
|
||||
def fake():
|
||||
_(u'This username is already taken. Please choose another.')
|
||||
_(u'You must type the same password each time')
|
||||
_(u'This email address is already in use. Please supply a different email address.')
|
47
accounts/models.py
Normal file
47
accounts/models.py
Normal file
@ -0,0 +1,47 @@
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.signals import user_logged_in
|
||||
from django.db.models.signals import post_save
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from lang.models import Language
|
||||
|
||||
class Profile(models.Model):
|
||||
user = models.ForeignKey(User, unique = True, editable = False)
|
||||
language = models.CharField(
|
||||
verbose_name = _(u"Interface Language"),
|
||||
max_length = 10,
|
||||
choices = settings.LANGUAGES
|
||||
)
|
||||
languages = models.ManyToManyField(
|
||||
Language,
|
||||
verbose_name = _('Languages'),
|
||||
blank = True,
|
||||
)
|
||||
secondary_languages = models.ManyToManyField(
|
||||
Language,
|
||||
verbose_name = _('Secondary languages'),
|
||||
related_name = 'secondary_profile_set',
|
||||
blank = True,
|
||||
)
|
||||
suggested = models.IntegerField(default = 0, db_index = True)
|
||||
translated = models.IntegerField(default = 0, db_index = True)
|
||||
|
||||
|
||||
@receiver(user_logged_in)
|
||||
def set_lang(sender, **kwargs):
|
||||
lang_code = kwargs['user'].get_profile().language
|
||||
kwargs['request'].session['django_language'] = lang_code
|
||||
|
||||
def create_profile_callback(sender, **kwargs):
|
||||
'''
|
||||
Automatically create profile when creating new user.
|
||||
'''
|
||||
if kwargs['created']:
|
||||
profile, newprofile = Profile.objects.get_or_create(user = kwargs['instance'])
|
||||
if newprofile:
|
||||
profile.save
|
||||
|
||||
post_save.connect(create_profile_callback, sender = User)
|
16
accounts/tests.py
Normal file
16
accounts/tests.py
Normal file
@ -0,0 +1,16 @@
|
||||
"""
|
||||
This file demonstrates writing tests using the unittest module. These will pass
|
||||
when you run "manage.py test".
|
||||
|
||||
Replace this with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
62
accounts/views.py
Normal file
62
accounts/views.py
Normal file
@ -0,0 +1,62 @@
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.core.mail import mail_admins
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from accounts.models import set_lang
|
||||
from accounts.forms import ProfileForm, UserForm, ContactForm
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ProfileForm(request.POST, instance = request.user.get_profile())
|
||||
userform = UserForm(request.POST, instance = request.user)
|
||||
if form.is_valid() and userform.is_valid():
|
||||
form.save()
|
||||
userform.save()
|
||||
set_lang(request.user, request = request, user = request.user)
|
||||
# Need to redirect to allow language change
|
||||
return HttpResponseRedirect('/accounts/profile/')
|
||||
else:
|
||||
form = ProfileForm(instance = request.user.get_profile())
|
||||
userform = UserForm(instance = request.user)
|
||||
|
||||
response = render_to_response('profile.html', RequestContext(request, {
|
||||
'form': form,
|
||||
'userform': userform,
|
||||
'title': _('User profile'),
|
||||
}))
|
||||
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, request.user.get_profile().language)
|
||||
return response
|
||||
|
||||
def contact(request):
|
||||
if request.method == 'POST':
|
||||
form = ContactForm(request.POST)
|
||||
if form.is_valid():
|
||||
mail_admins(
|
||||
form.cleaned_data['subject'],
|
||||
'Message from %s <%s>:\n\n%s' % (
|
||||
form.cleaned_data['name'],
|
||||
form.cleaned_data['email'],
|
||||
form.cleaned_data['message']
|
||||
))
|
||||
messages.add_message(request, messages.INFO, _('Message has been sent to administrator.'))
|
||||
return HttpResponseRedirect('/')
|
||||
else:
|
||||
initial = {}
|
||||
if request.user.is_authenticated():
|
||||
initial['name'] = request.user.get_full_name()
|
||||
initial['email'] = request.user.email
|
||||
if 'subject' in request.GET:
|
||||
initial['subject'] = request.GET['subject']
|
||||
form = ContactForm(initial = initial)
|
||||
|
||||
return render_to_response('contact.html', RequestContext(request, {
|
||||
'form': form,
|
||||
'title': _('Contact'),
|
||||
}))
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"browsers": [">1%", "not ie 11", "not op_mini all", "not dead"]
|
||||
}
|
||||
}]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "jcbrand/converse.js",
|
||||
"description": "Browser based XMPP instant messaging client",
|
||||
"type": "library",
|
||||
"license": "MPL-2.0",
|
||||
"minimum-stability": "stable",
|
||||
"homepage": "https://conversejs.org/",
|
||||
"keywords": ["xmpp", "messaging", "chat", "presence"],
|
||||
"require": {}
|
||||
}
|
293
conversejs.doap
293
conversejs.doap
@ -1,293 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:doap="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xmpp="https://linkmauve.fr/ns/xmpp-doap#" xmlns:schema="https://schema.org/" xml:lang="en">
|
||||
<Project xmlns="http://usefulinc.com/ns/doap#">
|
||||
<name>Converse.js</name>
|
||||
<shortdesc>Browser based XMPP chat client</shortdesc>
|
||||
<homepage rdf:resource="https://conversejs.org/"/>
|
||||
<bug-database rdf:resource="https://github.com/conversejs/converse.js/issues"/>
|
||||
<developer-forum rdf:resource="xmpp:discuss@conference.conversejs.org?join"/>
|
||||
<support-forum rdf:resource="xmpp:discuss@conference.conversejs.org?join"/>
|
||||
<category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-client"/>
|
||||
<programming-language>JavaScript</programming-language>
|
||||
<os>Browser</os>
|
||||
<os>Linux</os>
|
||||
<os>macOS</os>
|
||||
<os>Windows</os>
|
||||
<schema:logo rdf:resource="https://raw.githubusercontent.com/conversejs/converse.js/master/logo/conversejs-filled.svg"/>
|
||||
<repository>
|
||||
<GitRepository>
|
||||
<browse rdf:resource="https://github.com/conversejs/converse.js"/>
|
||||
<location rdf:resource="https://github.com/conversejs/converse.js.git"/>
|
||||
</GitRepository>
|
||||
</repository>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6120"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6121"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6122"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7395"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7590"/>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0004.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0030.html"/>
|
||||
<xmpp:since>0.8.2</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0045.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0048.html"/>
|
||||
<xmpp:since>2.0.1</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0050.html"/>
|
||||
<xmpp:since>7.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0054.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0059.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0060.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0066.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0077.html"/>
|
||||
<xmpp:since>0.8.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0085.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0115.html"/>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
<xmpp:note>advertises caps but no caching</xmpp:note>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0122.html"/>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
<xmpp:note>basic string field sub-type usage</xmpp:note>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0124.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0144.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0156.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0163.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0184.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0198.html"/>
|
||||
<xmpp:since>5.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0199.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0203.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0206.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0245.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0249.html"/>
|
||||
<xmpp:since>0.8.2</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0280.html"/>
|
||||
<xmpp:since>0.8.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0297.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0308.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0313.html"/>
|
||||
<xmpp:since>0.9.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0317.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0319.html"/>
|
||||
<xmpp:since>4.0.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0333.html"/>
|
||||
<xmpp:since>4.1.1</xmpp:since>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0352.html"/>
|
||||
<xmpp:since>0.9.4</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0357.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0359.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0363.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0371.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0372.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0382.html"/>
|
||||
<xmpp:since>3.3.3</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0384.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0393.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0410.html"/>
|
||||
<xmpp:since>5.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0421.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0422.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0424.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0425.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0437.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0454.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
</Project>
|
||||
</rdf:RDF>
|
@ -1,127 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Converse - Anonymous login demo</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js Converse" />
|
||||
|
||||
<!-- These files are NOT needed when using converse.js in your own project. -->
|
||||
<link rel="shortcut icon" type="image/ico" href="/dist/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/website.min.css" />
|
||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="/dist/converse.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body id="page-top" data-spy="scroll" class="converse-website">
|
||||
<section class="section-wrapper">
|
||||
<nav class="navbar sticky-top navbar-expand-lg" role="navigation">
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
|
||||
<span class="page-scroll">
|
||||
<a class="navbar-brand" href="/"><span class="converse-brand-heading">Home</span></a>
|
||||
<a class="navbar-brand" href="/demo"><span class="converse-brand-heading">Demos</span></a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section id="intro" class="intro" class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-md-offset-2">
|
||||
<h1 class="brand-heading fade-in">
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Converse</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="brand-heading__text">
|
||||
<span>converse<span class="subdued">.js</span></span>
|
||||
<p class="byline">messaging freedom</p>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p class="intro-text">Anonymous login demo</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
/*
|
||||
@licstart
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@licend
|
||||
*/
|
||||
converse.initialize({
|
||||
allow_logout: false, // No point in logging out when we have auto_login as true.
|
||||
allow_muc_invitations: false, // Doesn't make sense to allow because only
|
||||
// roster contacts can be invited
|
||||
allow_contact_requests: false, // Contacts from other servers cannot,
|
||||
// be added and anonymous users don't
|
||||
// know one another's JIDs, so disabling.
|
||||
authentication: 'anonymous',
|
||||
auto_login: true,
|
||||
auto_join_rooms: [
|
||||
'anonymous@conference.nomnom.im',
|
||||
],
|
||||
notify_all_room_messages: [
|
||||
'anonymous@conference.nomnom.im',
|
||||
],
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||
jid: 'nomnom.im', // XMPP server which allows anonymous login (doesn't
|
||||
// allow chatting with other XMPP servers).
|
||||
keepalive: true,
|
||||
hide_muc_server: true, // Federation is disabled, so no use in
|
||||
// showing the MUC server.
|
||||
play_sounds: true,
|
||||
show_controlbox_by_default: true,
|
||||
strict_plugin_dependencies: false,
|
||||
});
|
||||
</script>
|
||||
</html>
|
@ -1,103 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Converse - Anonymous login demo</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js Converse" />
|
||||
|
||||
<!-- These files are NOT needed when using converse.js in your own project. -->
|
||||
<link rel="shortcut icon" type="image/ico" href="../dist/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="../dist/website.min.css" />
|
||||
<noscript><p><img src="https://stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="/analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<link rel="manifest" href="../manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="../dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="../dist/converse.min.js"></script>
|
||||
|
||||
<style>
|
||||
.converse-container {
|
||||
height: 50vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
<body id="page-top" data-spy="scroll" class="converse-website">
|
||||
<section class="section-wrapper">
|
||||
<nav class="navbar sticky-top navbar-expand-lg" role="navigation">
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
|
||||
<span class="page-scroll">
|
||||
<a class="navbar-brand" href="/"><span class="converse-brand-heading">Home</span></a>
|
||||
<a class="navbar-brand" href="/demo"><span class="converse-brand-heading">Demos</span></a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
<section class="intro">
|
||||
<div class="intro-body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1 class="brand-heading fade-in" style="margin: 1.5em 0 0 0">
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
|
||||
<title>Home</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="brand-heading__text">
|
||||
<span>converse<span class="subdued">.js</span></span>
|
||||
<p class="byline">messaging freedom</p>
|
||||
</span>
|
||||
</h1>
|
||||
<p class="intro-text">Embedded MUC chat demo</p>
|
||||
<div class="converse-container">
|
||||
<converse-root></converse-root>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
converse.initialize({
|
||||
authentication: 'anonymous',
|
||||
auto_login: true,
|
||||
auto_join_rooms: [
|
||||
'anonymous@conference.nomnom.im',
|
||||
],
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||
jid: 'nomnom.im', // XMPP server which allows anonymous login (doesn't
|
||||
// allow chatting with other XMPP servers).
|
||||
notify_all_room_messages: [
|
||||
'anonymous@conference.nomnom.im',
|
||||
],
|
||||
singleton: true,
|
||||
locales_url: "../locale/{{{locale}}}/LC_MESSAGES/converse.json",
|
||||
view_mode: 'embedded',
|
||||
});
|
||||
</script>
|
||||
</html>
|
113
demo/index.html
113
demo/index.html
@ -1,113 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Converse Demos</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js Converse" />
|
||||
|
||||
<!-- These files are NOT needed when using converse.js in your own project. -->
|
||||
<link rel="shortcut icon" type="image/ico" href="/dist/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/website.min.css" />
|
||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="/dist/converse.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body id="page-top" data-spy="scroll" class="converse-website">
|
||||
<section class="section-wrapper">
|
||||
<nav class="navbar sticky-top navbar-expand-lg" role="navigation">
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
|
||||
<span class="page-scroll">
|
||||
<a class="navbar-brand" href="/"><span class="converse-brand-heading">Home</span></a>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section id="intro" class="intro" class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-md-offset-2">
|
||||
<h1 class="brand-heading fade-in">
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Home</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="brand-heading__text">
|
||||
<span>converse<span class="subdued">.js</span></span>
|
||||
<p class="byline">messaging freedom</p>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p class="intro-text">Demos:</p>
|
||||
<p class="intro-text">
|
||||
<ul style="list-style: none; font-size: 22px;">
|
||||
<li><a href="/fullscreen.html">As a fullscreen application</a></li>
|
||||
<li><a href="/demo/anonymous.html">Anonymous login</a></li>
|
||||
<li><a href="/demo/embedded.html">Single MUC chatroom embedded into the page</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
/*
|
||||
@licstart
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
@licend
|
||||
*/
|
||||
converse.initialize({
|
||||
// Please use this connection manager only for testing purposes
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/'
|
||||
});
|
||||
</script>
|
||||
</html>
|
50
dev.html
50
dev.html
@ -1,50 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Converse</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat" />
|
||||
<meta name="author" content="JC Brand" />
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js" />
|
||||
<link rel="manifest" href="./manifest.json">
|
||||
<link rel="shortcut icon" type="image/ico" href="images/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="dist/website.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="dist/converse.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="dist/converse.js"></script>
|
||||
</head>
|
||||
|
||||
<body class="reset" style="background-color: var(--global-background-color)">
|
||||
<div id="conversejs-bg"></div>
|
||||
<script>
|
||||
|
||||
converse.plugins.add('converse-debug', {
|
||||
initialize () {
|
||||
const { _converse } = this;
|
||||
window._converse = _converse;
|
||||
}
|
||||
});
|
||||
|
||||
converse.initialize({
|
||||
i18n: 'af',
|
||||
theme: 'dracula',
|
||||
auto_away: 300,
|
||||
enable_smacks: true,
|
||||
loglevel: 'debug',
|
||||
reuse_scram_keys: true,
|
||||
prune_messages_above: 100,
|
||||
message_archiving: 'always',
|
||||
muc_respect_autojoin: true,
|
||||
muc_show_logs_before_join: true,
|
||||
notify_all_room_messages: ['discuss@conference.conversejs.org'],
|
||||
view_mode: 'fullscreen',
|
||||
// websocket_url: 'wss://conversejs.org/xmpp-websocket',
|
||||
websocket_url: 'ws://chat.example.org:5380/xmpp-websocket',
|
||||
whitelisted_plugins: ['converse-debug'],
|
||||
// connection_options: { worker: '/dist/shared-connection-worker.js' }
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,48 +0,0 @@
|
||||
.brand-heading {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand-heading__text {
|
||||
font-size: 6rem;
|
||||
margin-left: 1rem;
|
||||
margin-top: -1rem;
|
||||
}
|
||||
|
||||
.subdued {
|
||||
color: darkgray;
|
||||
}
|
||||
|
||||
.byline {
|
||||
font-size: 30%;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
section h1 {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 25px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.details {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.prettyprint code {
|
||||
padding: 8px 12px;
|
||||
font-family: courier;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 64 KiB |
@ -1,169 +0,0 @@
|
||||
body {
|
||||
font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toctree-l1 > a {
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: 7px;
|
||||
}
|
||||
.navbar-brand img {
|
||||
float: left;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
padding-left: 15px;
|
||||
color: #716b7a;
|
||||
}
|
||||
|
||||
.sponsors-list {
|
||||
overflow-y: auto !important;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.bs-sidenav .sponsors-list li a:hover {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sponsors-list li {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.sponsors-list li a {
|
||||
background-color: transparent;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.centered-text-container {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.patreon-link-container {
|
||||
margin: 0.5em 0 1em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.patreon-link-container a {
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
#sidebar > .nav-list {
|
||||
max-height: 35vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.bs-sidenav .nav .nav > li > a {
|
||||
font-size: 100%;
|
||||
}
|
||||
.bs-sidenav .nav .nav .nav > li > a {
|
||||
font-size: 90%;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
/*
|
||||
Copyright (c) 2012 Terrence Ryan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#banner {
|
||||
height: 149px;
|
||||
width: 149px;
|
||||
overflow:hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#banner a {
|
||||
display: block;
|
||||
width: 235px;
|
||||
font-size: 14px;
|
||||
font-family: Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT",
|
||||
"Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma,
|
||||
Geneva, "Helvetica Neue", Helvetica, Arial, sans serif;
|
||||
background-color: #333;
|
||||
color: #FFF;
|
||||
word-spacing: 2px;
|
||||
text-decoration: none;
|
||||
padding: 5px 15px 5px 25px;
|
||||
|
||||
position:relative;
|
||||
left: 20px;
|
||||
top: -33px;
|
||||
text-align: center;
|
||||
|
||||
-moz-transform-origin: 0 0 ;
|
||||
-moz-transform:rotate(45deg);
|
||||
-moz-box-shadow: 1px 1px 5px 1px #666;
|
||||
|
||||
-webkit-transform-origin: 0 0 ;
|
||||
-webkit-transform:rotate(45deg);
|
||||
-webkit-box-shadow: 1px 1px 5px 1px #666;
|
||||
|
||||
-ms-transform-origin: 0 0 ;
|
||||
-ms-transform:rotate(45deg);
|
||||
-ms-box-shadow: 1px 1px 5px 1px #666;
|
||||
|
||||
transform-origin: 0 0 ;
|
||||
transform:rotate(45deg);
|
||||
box-shadow: 1px 1px 5px 1px #666;
|
||||
|
||||
background-image: linear-gradient(bottom, #000000 3%, #666666 5%, #000000 7%, #000000 93%, #666666 95%, #000000 97%);
|
||||
background-image: -o-linear-gradient(bottom, #000000 3%, #666666 5%, #000000 7%, #000000 93%, #666666 95%, #000000 97%);
|
||||
background-image: -moz-linear-gradient(bottom, #000000 3%, #666666 5%, #000000 7%, #000000 93%, #666666 95%, #000000 97%);
|
||||
background-image: -webkit-linear-gradient(bottom, #000000 3%, #666666 5%, #000000 7%, #000000 93%, #666666 95%, #000000 97%);
|
||||
background-image: -ms-linear-gradient(bottom, #000000 3%, #666666 5%, #000000 7%, #000000 93%, #666666 95%, #000000 97%);
|
||||
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left bottom,
|
||||
left top,
|
||||
color-stop(0.03, #000000),
|
||||
color-stop(0.05, #666666),
|
||||
color-stop(0.07, #000000),
|
||||
color-stop(0.93, #000000),
|
||||
color-stop(0.95, #666666),
|
||||
color-stop(0.97, #000000)
|
||||
);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Converse.js API Documentation <?js= title ?></title>
|
||||
<script src="scripts/prettify/prettify.js"></script>
|
||||
<script src="scripts/prettify/lang-css.js"></script>
|
||||
<script src="./analytics.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
<link type="text/css" rel="stylesheet" href="/docs/source/_static/api.css">
|
||||
<link rel="shortcut icon" href="/images/favicon.ico"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
<h1 class="brand-heading fade-in">
|
||||
<svg
|
||||
style="height: 8rem"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Converse</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="brand-heading__text">
|
||||
<span>converse<span class="subdued">.js</span></span>
|
||||
<p class="byline">API Documentation</p>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<h1 class="page-title"><?js= title ?></h1>
|
||||
<?js= content ?>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="/docs/html/index.html">Docs Entrypoint</a></h2>
|
||||
<?js= this.nav ?>
|
||||
</nav>
|
||||
|
||||
<br class="clear">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc <?js= env.version.number ?></a><?js if(env.conf.templates && env.conf.templates.default && env.conf.templates.default.includeDate !== false) { ?> on <?js= (new Date()) ?><?js } ?>
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
{# Import the theme's layout. #}
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{# Custom CSS overrides #}
|
||||
{% set css_files = css_files + ['_static/style.css'] %}
|
||||
{% set script_files = script_files + ["../../analytics.js"] %}
|
||||
|
||||
{# Add some extra stuff before and use existing with 'super()' call. #}
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
{#
|
||||
basic/localtoc.html
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sphinx sidebar template: local table of contents.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
#}
|
||||
{%- if display_toc %}
|
||||
<h3 class="sidebar-title"><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
|
||||
{{ toc }}
|
||||
{%- endif %}
|
@ -1,22 +0,0 @@
|
||||
<span class="centered-text-container">
|
||||
<h4 class="sidebar-title">Sponsored by</h4>
|
||||
</span>
|
||||
<ul class="sponsors-list">
|
||||
<li><a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 10em" src="/media/logos/bairesdev-primary.png" alt="BairesDev">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://blokt.com/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 9em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 9em" src="/media/logos/primesound.png" alt="Prime Sound">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://www.keycdn.com/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="height: 2.5em" src="/logo/keycdn.png" alt="KeyCDN">
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="centered-text-container patreon-link-container"><a href="https://conversejs.org#sponsors">Become a sponsor</a></span>
|
@ -1,12 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/api/index.rst">Edit me on GitHub</a></div>
|
||||
|
||||
============================================
|
||||
The API documentation (generated with JSDoc)
|
||||
============================================
|
||||
|
||||
This document is a stub. It shouldn't show at all, instead it's a hack in order
|
||||
to link to the JSDoc output.
|
||||
|
||||
See https://stackoverflow.com/questions/27979803/external-relative-link-in-sphinx-toctree-directive
|
@ -1,107 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/builds.rst">Edit me on GitHub</a></div>
|
||||
|
||||
|
||||
.. _builds:
|
||||
|
||||
=================
|
||||
Generating builds
|
||||
=================
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 3
|
||||
:local:
|
||||
|
||||
|
||||
.. warning:: There current documentation in this section does not adequately
|
||||
explain how to create custom bundles.
|
||||
|
||||
.. Note:: Please make sure to read the section :doc:`development` and that you have installed
|
||||
all development dependencies (long story short, you should be able to just run ``make dev``)
|
||||
|
||||
.. _creating_builds:
|
||||
|
||||
Creating JavaScript and CSS bundles and distribution files
|
||||
==========================================================
|
||||
|
||||
Converse uses `webpack <https://webpack.js.org/>`_ to create the final JavaScript and CSS distribution files.
|
||||
|
||||
The generated distribution files are all placed in the ``./dist`` directory.
|
||||
The Converse repository does not include ``dist`` directory by default.
|
||||
|
||||
To generate the ``./dist`` directory and all CSS and JavaScript bundles, simply run ``make dist``.
|
||||
|
||||
When you're developing, and constantly changing code, you can run ``make watch``
|
||||
to let the bundles be automatically generated as soon as you edit a file.
|
||||
|
||||
.. note::
|
||||
|
||||
If you're on Windows or don't have GNU Make installed, you can run ``npm build``
|
||||
to build all the distribution files.
|
||||
|
||||
|
||||
Creating custom bundles
|
||||
=======================
|
||||
|
||||
One reason you might want to create your own bundles, is because you want to
|
||||
remove some of the core plugins of Converse, or perhaps you want to include
|
||||
your own.
|
||||
|
||||
To add or remove plugins from the build, you need to modify the
|
||||
`src/converse.js <https://github.com/conversejs/converse.js/blob/master/src/converse.js>`_ file.
|
||||
|
||||
You'll find a section marked ``/* START: Removable components`` and
|
||||
``/* END: Removable components */``.
|
||||
|
||||
In this section is listed the Converse plugins that will make up a bundle.
|
||||
|
||||
You could for example decide to disable the ControlBox altogether by removing
|
||||
the ``converse-controlbox`` plugin.
|
||||
|
||||
After doing so, you need to run ``make dist`` again in the root or your
|
||||
Converse repository, in order to generate the new build.
|
||||
|
||||
Be aware that some plugins might have dependencies on other plugins, so if you
|
||||
remove a certain plugin but other included plugins still depend on it, then it
|
||||
will still be included in your build.
|
||||
|
||||
To see which other plugins a particular plugin depends on, open it up in your
|
||||
text editor and look at the list specified as the second parameter to the
|
||||
``define`` call, near the top of the file. This list specifies the dependencies
|
||||
of that plugin.
|
||||
|
||||
Besides the standard build, the Converse repository includes configuration
|
||||
for certain other non-standard builds, which we'll now mention below.
|
||||
|
||||
Excluding all 3rd party dependencies
|
||||
------------------------------------
|
||||
|
||||
The ``dist/converse-no-dependencies.js`` bundle contains only the core Converse
|
||||
code and none of the 3rd party dependencies. This might be useful if you need
|
||||
to load the dependencies separately.
|
||||
|
||||
To generate this bundle, you can run:
|
||||
|
||||
::
|
||||
|
||||
make dist/converse-no-dependencies.js
|
||||
make dist/converse-no-dependencies.min.js
|
||||
|
||||
Headless build
|
||||
--------------
|
||||
|
||||
Converse also has a special build called the `headless build`.
|
||||
|
||||
You can generate it by running ``make dist/converse-headless.js``
|
||||
|
||||
The headless build is a bundle of all the non-UI parts of Converse, and its aim
|
||||
is to provide you with an XMPP library (and application) on which you can build
|
||||
your own UI.
|
||||
|
||||
It's also installable as `@converse/headless <https://www.npmjs.com/package/@converse/headless>`_.
|
||||
|
||||
The main distribution of Converse relies on the headless build.
|
||||
|
||||
The file `src/headless/headless.js <https://github.com/jcbrand/converse.js/blob/master/src/headless/headless.js>`_
|
||||
is used to determine which plugins are included in the build.
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"plugins": ["plugins/markdown"],
|
||||
"templates": {
|
||||
"default": {
|
||||
"layoutFile": "_templates/jsdoc_layout.tmpl"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Converse documentation build configuration file, created by
|
||||
# sphinx-quickstart on Fri Apr 26 20:48:03 2013.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.todo']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Converse'
|
||||
copyright = u'2018, JC Brand'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '10.1.6'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '10.1.6'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
import sphinx_bootstrap_theme
|
||||
html_theme = 'bootstrap'
|
||||
html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# (Optional) Logo. Should be small enough to fit the navbar (ideally 24x24).
|
||||
# Path should be relative to the ``_static`` files directory.
|
||||
html_logo = "_static/logo.svg"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a
|
||||
# theme further.
|
||||
html_theme_options = {
|
||||
# Navigation bar title. (Default: ``project`` value)
|
||||
'navbar_title': "Converse",
|
||||
# Tab name for entire site. (Default: "Site")
|
||||
'navbar_site_name': "Table of Contents",
|
||||
# A list of tuples containing pages or urls to link to.
|
||||
# Valid tuples should be in the following forms:
|
||||
# (name, page) # a link to a page
|
||||
# (name, "/aa/bb", 1) # a link to an arbitrary relative url
|
||||
# (name, "http://example.com", True) # arbitrary absolute url
|
||||
# Note the "1" or "True" value above as the third argument to indicate
|
||||
# an arbitrary url.
|
||||
'navbar_links': [
|
||||
("Homepage", "https://conversejs.org", True)
|
||||
],
|
||||
# Render the next and previous page links in navbar. (Default: true)
|
||||
'navbar_sidebarrel': True,
|
||||
# Render the current pages TOC in the navbar. (Default: true)
|
||||
'navbar_pagenav': True,
|
||||
# Tab name for the current pages TOC. (Default: "Page")
|
||||
'navbar_pagenav_name': "Current Page",
|
||||
# Global TOC depth for "site" navbar tab. (Default: 1)
|
||||
# Switching to -1 shows all levels.
|
||||
'globaltoc_depth': 2,
|
||||
# Include hidden TOCs in Site navbar?
|
||||
#
|
||||
# Note: If this is "false", you cannot have mixed ``:hidden:`` and
|
||||
# non-hidden ``toctree`` directives in the same page, or else the build
|
||||
# will break.
|
||||
#
|
||||
# Values: "true" (default) or "false"
|
||||
'globaltoc_includehidden': "true",
|
||||
# HTML navbar class (Default: "navbar") to attach to <div> element.
|
||||
# For black navbar, do "navbar navbar-inverse"
|
||||
'navbar_class': "navbar",
|
||||
# Fix navigation bar to top of page?
|
||||
# Values: "true" (default) or "false"
|
||||
'navbar_fixed_top': "true",
|
||||
# Location of link to source.
|
||||
# Options are "nav" (default), "footer" or anything else to exclude.
|
||||
'source_link_position': "footer",
|
||||
# Bootswatch (http://bootswatch.com/) theme.
|
||||
# Options are nothing (default) or the name of a valid theme
|
||||
# such as "amelia" or "cosmo".
|
||||
# 'bootswatch_theme': "yeti",
|
||||
# Choose Bootstrap version.
|
||||
# Values: "3" (default) or "2" (in quotes)
|
||||
'bootstrap_version': "3",
|
||||
}
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = "_static/favicon.ico"
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
html_sidebars = {'**': ['sponsors.html', 'localtoc.html', 'sourcelink.html', 'searchbox.html']}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Conversejsdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Conversejs.tex', u'Converse Documentation',
|
||||
u'JC Brand', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'conversejs', u'Converse Documentation',
|
||||
[u'JC Brand'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'Conversejs', u'Converse Documentation',
|
||||
u'JC Brand', 'Converse', 'Open Source XMPP webchat',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
File diff suppressed because it is too large
Load Diff
@ -1,139 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/dependencies.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`development`:
|
||||
|
||||
============================
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Installing the 3rd party dependencies
|
||||
=====================================
|
||||
|
||||
To develop and customize Converse, you'll first need to check out Converse's Git
|
||||
repository:
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/conversejs/converse.js.git
|
||||
cd converse.js
|
||||
|
||||
|
||||
We use development tools which depend on Node.js and NPM (the Node package manager).
|
||||
|
||||
It's recommended that you use `NVM <https://github.com/nvm-sh/nvm>`_ (the Node version manager)
|
||||
to make sure you have the right version of Node.
|
||||
|
||||
Refer to the `NVM Github page <https://github.com/nvm-sh/nvm#install--update-script>`_ for instructions on how to install it.
|
||||
|
||||
Once NVM is installed, you can run the following inside your checkout of the Converse Git repository:
|
||||
|
||||
::
|
||||
|
||||
nvm install
|
||||
|
||||
.. note::
|
||||
You will always have to first run ``nvm install`` in a new terminal session before working on Converse.
|
||||
|
||||
|
||||
To set up the Converse development environment, you now run ``make dev``.
|
||||
|
||||
::
|
||||
|
||||
make dev
|
||||
|
||||
Alternatively, if you're using Windows, or don't have GNU Make installed, you can run the
|
||||
following:
|
||||
|
||||
::
|
||||
|
||||
npm install
|
||||
npm run lerna
|
||||
|
||||
This will install the Node development tools and Converse's dependencies.
|
||||
|
||||
The front-end dependencies are those JavaScript files on which
|
||||
Converse directly depends and which will be loaded in the browser as part of
|
||||
the bundle in ``dist/converse.js`` (or ``dist/converse.min.js``).
|
||||
|
||||
To see the 3rd party dependencies (not just the front-end dependencies, but
|
||||
also ones necessary for development tasks like making builds), take a look at
|
||||
the list under the ``devDependencies`` in `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
|
||||
|
||||
.. note::
|
||||
After running ```make dev```, you should now have a new *node_modules* directory
|
||||
which contains all the external dependencies of Converse.
|
||||
If this directory does NOT exist, something must have gone wrong.
|
||||
Double-check the output of ```make dev``` to see if there are any errors
|
||||
listed. For support, you can ask in our chatroom: `dicuss@conference.conversejs.org <xmpp:discuss@conference.conversejs.org>`_.
|
||||
|
||||
If you don't have an XMPP client installed, follow this link to
|
||||
`conversejs.org <https://conversejs.org/fullscreen#converse/room?jid=discuss@conference.conversejs.org>`_
|
||||
where you can log in and be taken directly to the chatroom.
|
||||
|
||||
|
||||
.. _`dependency-libsignal`:
|
||||
|
||||
Libsignal
|
||||
---------
|
||||
|
||||
If you want OMEMO encryption, you need to load `libsignal <https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in your page.
|
||||
|
||||
For example::
|
||||
|
||||
<script src="3rdparty/libsignal-protocol-javascript/dist/libsignal-protocol.js"></script>
|
||||
|
||||
The reason libsignal needs to be loaded separately is because it's released
|
||||
under the `GPLv3 <https://github.com/signalapp/libsignal-protocol-javascript/blob/master/LICENSE>`_
|
||||
which requires all other dependent JavaScript code to also be open sourced under the same
|
||||
license. You might not be willing to adhere to those terms, which is why you
|
||||
need to decide for yourself whether you're going to load libsignal or not.
|
||||
|
||||
|
||||
.. _`webserver`:
|
||||
|
||||
Setting up a webserver
|
||||
======================
|
||||
|
||||
When making changes to Converse, either development or theming changes,
|
||||
you'll want to preview them in your browser.
|
||||
|
||||
For this, you'll need to serve the development files via a web server,
|
||||
so that you can see your local changes in the browser.
|
||||
|
||||
Manually starting a web server
|
||||
------------------------------
|
||||
|
||||
To both set up the development environment and also start up a web browser to
|
||||
serve the files for you, you can run::
|
||||
|
||||
make serve
|
||||
|
||||
.. note::
|
||||
To run the "make" commands, you'll need `GNUMake <https://www.gnu.org/software/make>`_
|
||||
installed on your computer. If you use GNU/Linux or \*BSD, it should be installed or
|
||||
available via your package manager. For Mac, you'll need to install XCode and in
|
||||
Windows you can use `Chocolatey <https://chocolatey.org/>`_.
|
||||
|
||||
After running ``make serve`` you can open http://localhost:8000 in your webbrowser to see the Converse website.
|
||||
|
||||
When developing or changing the theme, you'll want to load all the
|
||||
unminified JS and CSS resources as separate files. To do this, open http://localhost:8000/dev.html instead.
|
||||
|
||||
You might want to open `dev.html <https://github.com/conversejs/converse.js/blob/master/dev.html>`_ in your text editor or IDE as well, to see
|
||||
how ``converse.initialize`` is called and to potentially change any of the
|
||||
settings.
|
||||
|
||||
Starting a web server with live reloading
|
||||
-----------------------------------------
|
||||
|
||||
Alternatively, if you want to have live reloading whenever any of the source files change, you
|
||||
can run ``make devserver`` (which will use `webpack-dev-server <https://github.com/webpack/webpack-dev-server>`_).
|
||||
|
||||
Instead of ``dev.html`` being used, `webpack.html <https://github.com/conversejs/converse.js/blob/master/webpack.html>`_
|
||||
is now being used as the HTML template, and you'll need to modify that file if
|
||||
you want to change the settings passed to ``converse.initialize``.
|
||||
|
||||
If you're running ``make devserver``, you need to open http://localhost:8080.
|
||||
|
@ -1,32 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/development.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`development`:
|
||||
|
||||
===========
|
||||
Development
|
||||
===========
|
||||
|
||||
Welcome to the developer documentation of Converse.js.
|
||||
|
||||
Here you will learn how to add new features and how you can create your own
|
||||
customized version of Converse.
|
||||
|
||||
Converse is a community project and largely volunteer driven.
|
||||
|
||||
We're grateful for your contributions, so please don't hesitate to
|
||||
make a `Github pull request <https://help.github.com/categories/collaborating-with-issues-and-pull-requests/>`_
|
||||
to fix a bug or to add new functionality.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
setup_dev_environment
|
||||
plugin_development
|
||||
api/index
|
||||
testing
|
||||
other_frameworks
|
||||
builds
|
||||
style_guide
|
@ -1,55 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/documentation.rst">Edit me on GitHub</a></div>
|
||||
|
||||
=====================
|
||||
Writing Documentation
|
||||
=====================
|
||||
|
||||
.. note:: Contributions to the documentation are much appreciated.
|
||||
|
||||
What is used to write the documentation?
|
||||
========================================
|
||||
|
||||
This documentation is written in `Sphinx <http://sphinx-doc.org/>`_, a
|
||||
documentation generator written in `Python <http://python.org>`_.
|
||||
|
||||
The documentation is written in `reStructuredText (reST) <http://sphinx-doc.org/rest.html>`_,
|
||||
a very easy to write plain text format, relatively similar to Markdown.
|
||||
|
||||
So see what the source looks like, click the **Source** link in the footer of
|
||||
this page.
|
||||
|
||||
Where is the documentation?
|
||||
===========================
|
||||
|
||||
The reST documentation files are located in the
|
||||
`converse.js code repository <https://github.com/jcbrand/converse.js/tree/master/docs/source>`_
|
||||
under ``docs/source``.
|
||||
|
||||
How to generate HTML from the source files?
|
||||
===========================================
|
||||
|
||||
Generate the HTML
|
||||
-----------------
|
||||
|
||||
After installing the dependencies, you can generate the HTML by running::
|
||||
|
||||
make html
|
||||
|
||||
The HTMl files will be located in ``./docs/html``
|
||||
|
||||
What ``make html`` does for you is it installs `zc.buildout <http://www.buildout.org/en/latest/>`_
|
||||
which is used to install Sphinx and all its dependencies.
|
||||
|
||||
You'll need to have Python and `Virtualenv <https://virtualenv.pypa.io/en/latest/>`_ available on your computer.
|
||||
|
||||
.. warning:: When contributing, please don't commit any generated html files.
|
||||
|
||||
Serving the documentation
|
||||
-------------------------
|
||||
|
||||
To view the generated docs, you can run ``make serve`` and then open
|
||||
http://localhost:8000/docs/html/index.html in your browser.
|
||||
|
||||
|
@ -1,191 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/features.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`features`:
|
||||
|
||||
========
|
||||
Features
|
||||
========
|
||||
|
||||
File sharing (`XEP-0363 HTTP File Upload <https://xmpp.org/extensions/xep-0363.html>`_)
|
||||
=======================================================================================
|
||||
|
||||
Converse supports file sharing by first uploading the file to a file server and
|
||||
then sending the file's URL to the recipient.
|
||||
|
||||
The file server that is used is configured by the XMPP server admin, and is not
|
||||
something that Converse has any control over.
|
||||
|
||||
Often when people report file sharing not working, it's because the file server
|
||||
is not configured to allow file uploads from other domains.
|
||||
|
||||
The file server needs to be configured for `Cross-Origin resource sharing <https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS>`_
|
||||
(known by the acronym CORS). Specifically, it needs to add a
|
||||
``Access-Control-Allow-Origin`` header which includes the domain hosting
|
||||
Converse.
|
||||
|
||||
.. _`feature-omemo`:
|
||||
|
||||
End to end message encryption (`XEP-0384 OMEMO <https://xmpp.org/extensions/xep-0384.html>`_)
|
||||
=============================================================================================
|
||||
|
||||
.. note::
|
||||
Converse versions older than 8.0.0 do NOT support encryption or decryption
|
||||
of uploaded files. Files will be uploaded WITHOUT ENCRYPTION, even when
|
||||
OMEMO is enabled.
|
||||
|
||||
.. note::
|
||||
For end-to-end encryption via OMEMO, you'll need to load `libsignal-protocol.js
|
||||
<https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in
|
||||
your page. Take a look at the section on :ref:`libsignal <dependency-libsignal>` and the
|
||||
:ref:`security considerations around OMEMO <feature-omemo>`.
|
||||
|
||||
Converse supports OMEMO encryption based on the
|
||||
`Signal Protocol <https://github.com/signalapp/libsignal-protocol-javascript>`_.
|
||||
|
||||
The Signal Protocol is session-oriented. Clients establish a session, which is
|
||||
then used for all subsequent encrypt/decrypt operations. There is no need to
|
||||
ever tear down a session once one has been established.
|
||||
|
||||
This means that a session needs to be stored permanently after logging out.
|
||||
|
||||
Converse stores this session information in the browser's `IndexedDB <https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API>`_
|
||||
or `localStorage <https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage>`_
|
||||
database, depending on the value provided to :ref:`persistent-store`.
|
||||
|
||||
If you've checked the "This is not a trusted device" checkbox when logging in,
|
||||
then `sessionStorage <https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage>`_
|
||||
is used instead of localStorage and all data is cleared when you log out.
|
||||
|
||||
For this reason, OMEMO is disabled when you've indicated that you're using
|
||||
an untrusted device. You would in any case not be able to decrypt previously
|
||||
received OMEMO messages, due to the Signal Protocol's forward secrecy and the
|
||||
fact that you don't have a pre-existing session.
|
||||
|
||||
Security considerations for browser-based crypto
|
||||
------------------------------------------------
|
||||
|
||||
Crypto apps deployed via regular web hosting can be described as relying on
|
||||
"host-based" security.
|
||||
|
||||
Host-based security services require you to trust the host every time you access
|
||||
it, whereas with installable desktop software you trust the host when you
|
||||
download/install the software (and whenever it gets updated).
|
||||
|
||||
The dynamic nature of "host-based" systems makes it impractical for security
|
||||
researchers to do security audits because the hosted code can change at any
|
||||
time.
|
||||
|
||||
In such a setup you need to fully trust the host that serves you the JavaScript code.
|
||||
|
||||
The host that serves the JavaScript code is not necessarily the same host that
|
||||
stores and procesess your chat messages. So using OMEMO can still protect your
|
||||
messages from snooping on the XMPP server where they're stored encrypted.
|
||||
|
||||
In other words, you do have to trust the webserver that hosts Converse for you,
|
||||
but you don't necessarily have to trust the XMPP server (if it's on a different host),
|
||||
because it never gets hold of your private key.
|
||||
|
||||
One way to improve this situation is to host Converse yourself, especially if
|
||||
you host it locally on your own machine. If you're not able to do that, then
|
||||
at least make sure you use a reputable host that serves files over HTTPS and
|
||||
that set `CSP <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy>`_
|
||||
headers.
|
||||
|
||||
Due to these reasons, it's NOT a good idea to use encrypted messaging with a
|
||||
browser-based solution in life-threatening situations.
|
||||
|
||||
Security can be increased by using an installable app (like `Converse Desktop <https://github.com/conversejs/converse-desktop>`_).
|
||||
|
||||
For further reading on the challenges of web-based crypto, take a look at these
|
||||
articles:
|
||||
|
||||
* `What's wrong with webcrypto? <https://tonyarcieri.com/whats-wrong-with-webcrypto>`_
|
||||
* `Heartbleed and JavaScript crypto <https://tankredhase.com/2014/04/13/heartbleed-and-javascript-crypto/>`_
|
||||
|
||||
OMEMO in Multi-user chats (MUC)
|
||||
-------------------------------
|
||||
|
||||
Converse supports OMEMO encryption in groupchats, but only if the groupchat is
|
||||
set to `members only` and `non-anonymous`. This is the same criteria used by
|
||||
the popular Android XMPP client `Conversations <https://conversations.im/>`_.
|
||||
|
||||
If the groupchat is configured properly, you'll see the lock icon in the
|
||||
toolbar.
|
||||
|
||||
|
||||
Open chats via URL
|
||||
==================
|
||||
|
||||
From version 3.3.0, converse.js now has the ability to open chats (private or
|
||||
groupchat) based on the URL fragment.
|
||||
|
||||
A room (aka groupchat) can be opened with a URL fragment such as `#converse/room?jid=room@domain`
|
||||
and a private chat with a URL fragment such as
|
||||
`#converse/chat?jid=user@domain`.
|
||||
|
||||
|
||||
Notifications
|
||||
=============
|
||||
|
||||
From version 0.8.1 Converse can play a sound notification when you receive a
|
||||
message.
|
||||
|
||||
For more info, refer to the :ref:`play-sounds` configuration setting.
|
||||
|
||||
It can also show `desktop notification messages <https://developer.mozilla.org/en-US/docs/Web/API/notification>`_
|
||||
when the browser is not currently visible.
|
||||
|
||||
For more info, refer to the :ref:`show-desktop-notifications` configuration setting.
|
||||
|
||||
Multilingual Support
|
||||
====================
|
||||
|
||||
Converse is translated into over 30 languages. Translations can be added or
|
||||
updated on `Weblate <https://hosted.weblate.org/projects/conversejs/>`_.
|
||||
|
||||
Translations are supplied in JSON format and are loaded on demand. Converse will expect to find the
|
||||
translations in the ``/dist/locales`` path of your site. This path can be
|
||||
changed via the :ref:`assets_path` configuration setting.
|
||||
|
||||
|
||||
Moderating chatrooms
|
||||
====================
|
||||
|
||||
Here are the different commands that may be used to moderate a chatroom:
|
||||
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| Event Type | When is it triggered? | Example (substitue $nickname with an actual user's nickname) |
|
||||
+============+==============================================================================================+===============================================================+
|
||||
| **ban** | Ban a user from the chatroom. They will not be able to join again. | /ban $nickname |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **clear** | Clear the messages shown in the chatroom. | /clear |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **deop** | Make a moderator a normal occupant. | /deop $nickname [$reason] |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **help** | Show the list of available commands. | /help |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **kick** | Kick a user out of a room. They will be able to join again. | /kick $nickname [$reason] |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **me** | Speak in the 3rd person. | /me $message |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **mute** | Remove a user's ability to post messages to the room. They will still be able to observe. | /mute $nickname [$reason] |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **nick** | Change your nickname. | /nick $nickname |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **op** | Make a normal occupant a moderator. | /op $nickname [$reason] |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **topic** | Set the topic of the chatroom. | /topic ${topic text} |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| **voice** | Allow a muted user to post messages to the room. | /voice $nickname [$reason] |
|
||||
+------------+----------------------------------------------------------------------------------------------+---------------------------------------------------------------+
|
||||
|
||||
Passwordless login with client certificates
|
||||
===========================================
|
||||
|
||||
Converse supports the SASL-EXTERNAL authentication mechanism, which can be
|
||||
used together with x509 client certificates to enable passwordless login or
|
||||
even 2-factor authentication.
|
||||
|
||||
For more info, `read this blog post <https://opkode.com/blog/strophe_converse_sasl_external/>`_.
|
Binary file not shown.
Before Width: | Height: | Size: 81 KiB |
@ -1 +0,0 @@
|
||||
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0" version="7.3.5" editor="www.draw.io" type="device"><diagram name="Page-1" id="e3a06f82-3646-2815-327d-82caf3d4e204">7Vtbc5s4FP41ntl9KKMLuj3GTi8P6Wx28tDuU0cG2abFyAMkcfrrVwJhA8Kxk+Jsmll3xrWOhCS+8+k7R4JM8Gy9/ZjLzeqzjlU6QSDeTvDlBCEREvNtDQ+1gQhQG5Z5EtcmuDfcJD+VMzbNbpNYFZ2GpdZpmWy6xkhnmYrKjk3mub7vNlvotDvqRi6VZ7iJZNpYA7K3f0nicuXskIp9xSeVLFducI5YXTGX0Y9lrm8zN2KmM1XXrGXTjbvLYiVjfd8y4fcTPMu1Lutf6+1MpRbXBrPmuvKhmegET1flOjUFaH5W1R8OXAxPudjcV66ysj3cof6oZDFfYKQAjgVm4B1x0NzJ9LYZoT/k/Sop1c1GRrZ8b7jTncMiSdOZTnVetcbvL+0/a9dZ6VgCQ1Muylz/UE3LCmI8vVN5mRgfXqTJMjPmUm8Gb8sBYZurbcvkbvOj0mtV5g+miaslDS0dm6lw7LjfMwNh12bVIoW51HHS8XG563sPrPnhsD3gNzY2rIvFAkXRUVhNy5jOKaFHsPWAHID7ILYo7GIbNkrRwpaSAWwhx7+O7Y4Lo2EbE8Xj8BRsOZpjelZsGe3zlvq8ZefC1tcH7oE905m5w0IF34sJoqkZfjrPza9lWSFA5dpCkc0L+19+m2VJtrRDZHZu9kbU3EquFXyV/6rnpOKL46viUbGpLnUTACMoD6Ss40FGoedBDAc8iCE/gwcx9TBWsQmcruigqYKfiisIOoAXpcx3yNo6lcXt4ndVlg/OIG9LbUw6L1d6qTOZXmmLcO24noNMNxc26O+nYCwfEntf1RRqBzZhHFX1Boqvrroq/GMLQWiI7wzXKk8MYip3rQ56s9C3eaQOINYkLzJfqsY1tckC9ygFcpXKMrnr5ilD7nSXXuvEzGxHHYp61OEwYEBAgNxXt8N6hq6PHkV2k3oea3yNnaWJcuO0udSsqSs5V+m1LpIy0XZtzXVZ6rXxgSw2dba3SLaWYG1yDS/IwbVr8q6NHXK9XdrsNYiSMk+2QSo35qJvyJcGSqfog0FkatrHduqtOgAonc0GWDnC8kfAUFK0Ph2PcuSnISZB9cWA02CEPMRXA/ZG1OCkpU38lcz+o5UscBBCRriov15uJdPfZCVvYvmKFnGIAwJaH9rxpqDYD+kDEZ0+wpvnL2H+RpbwPqAHzHWxC+pmt3YgpqttUtYXEcBcub4GYOjKz8oDmC8W4oXEgpKuWIS9LuppevLgddTfPDBGA0AoRYLjEJEQnUt1sCcyX7pZvr9PeF3q00x0lD0c7rmBY+HJRcia+N4WDIbGiPrkf2884g0Rhi/qDf8oqPbGjcrvBjbAh6CvUXwK7jtnPQX6SEYr9a2o5zZOPE57d5LXCE+lm2eqFuU4riZ9IWX+1rsxtR0t2BiO9o9Sp3/dfDIWg5DpOTXxKKvCRGqnbEhQ6OiHCTVHD1H+UEm5slQxPJFZLNPqeHq267moQbKBQC9sCFuZavD18/W1vaRy5Z+vjWf3al6xLLHhd7rSefLT0EY2Y/Q5ExkGVIRsSLMzjKEQpEsbwgbOM/FAegd+nTTQF2vnuNepD43fKuxP91JbE8hIi713Cr0rtxc7HdJ1MYbf3syx2i6fFoB08mncFIfT6V5WfDS/dvLYzq9r8o+eT2OBAoEYEUiQUAgAcZcoorf7PjW9Nv12O0I9Io2XUEM/mFxdXlw3kn8RVfAgcJnkZr1rx90X1Ykq5NvPYbGIm9m1EoqeELxccsB4b3M0cC5PB9SC8zGSg4HnwL+7XhDMW3rxzmzA4aENeGurL0LY2+rjI+f3TxUa+HJKw/vPenCPKqdKC4Xdjuj5pGVgs+5R84nPpnmkTns2PeckJODgHnGMrAB2czkxkBXsFuP4z6ZDD9upNEl+Fk+aB59ys0nNnVdy98q23Z3c7hwZG4dd3wzk2efL2JpjkTekwLijwCDgHB0XYIJwV4ABQuMK8MBJar0wRtffsPeWD+c9opysvwgPU/MM+uu/UnHz95UxfFZFYd9xM+ldHq2q/O517f1iWcq5LNQJadxZ9+uM9HZ+1NeREA3pCBlBR7D/Ut5vqiN7TeCkKwkHn76cLggvkH2xsJs0Ef7c7AscINQZnpS8tSgEA0BwJwqZGH48CoH+Ez9MxLhRCPs8ZOcJQgAEvaQTsABCATiBZkcAmrOip9KSsO7LI4zZlQpESDGzpxH8bCR9e4dbIes+LBYncJTTXqYEx2Xo0Eb1TIkS6b+H1GxcnyyVuJco9TOuEVn4tt5VOs6O0b2OGO4rk4ABwYTBEPHq+3kswESciQWmuP9jirr5/q9V8Pt/AQ==</diagram></mxfile>
|
@ -1,54 +0,0 @@
|
||||
.. Converse documentation master file, created by
|
||||
sphinx-quickstart on Fri Apr 26 20:48:03 2013.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/index.rst">Edit me on GitHub</a></div>
|
||||
|
||||
======================
|
||||
Converse Documentation
|
||||
======================
|
||||
|
||||
Preface
|
||||
=======
|
||||
|
||||
This is the official documentation for Converse. If you'd like to
|
||||
contribute, please read the :doc:`documentation` page.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Converse is a free and open-source `XMPP <https://xmpp.org/about-xmpp/>`_
|
||||
chat client written in JavaScript which can be tightly integrated into any website.
|
||||
|
||||
The benefit of using converse.js as opposed to relying on a SaaS
|
||||
(software-as-a-service) solution, is that your users can have a much more
|
||||
customized, streamlined and integrated webchat experience and that you have
|
||||
control over the data. The latter being a requirement for many sites dealing
|
||||
with sensitive information.
|
||||
|
||||
You'll likely want users who are authenticated on your website, to also
|
||||
automatically be authenticated on the XMPP server. In order to do this, you'll
|
||||
have to add some server-side code for your website.
|
||||
|
||||
The :ref:`what-you-will-need` and :ref:`session-support` sections provide more information on how to achieve this.
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
quickstart
|
||||
features
|
||||
setup
|
||||
session
|
||||
configuration
|
||||
development
|
||||
theming
|
||||
security
|
||||
translations
|
||||
troubleshooting
|
||||
documentation
|
@ -1,59 +0,0 @@
|
||||
# The Converse API documentation
|
||||
|
||||
Welcome to the new Converse API documentation, generated with
|
||||
[JSDoc](http://usejsdoc.org/).
|
||||
|
||||
## The public and private API
|
||||
|
||||
Converse has a public API and a private API only available to plugins.
|
||||
|
||||
The reason we make this distinction between public and private is so that API
|
||||
methods which could be used to "impersonate" the user, for example by
|
||||
sending messages on their behalf, are not available to random scripts running
|
||||
in your website.
|
||||
|
||||
The public API is accessible via the [window.converse](/docs/html/api/converse.html)
|
||||
global and is therefore available to any JavaScript running in the page.
|
||||
|
||||
The private API is only accessible to plugins, which have been whitelisted and
|
||||
registered before [converse.initialize](/docs/html/api/converse.html#.initialize)
|
||||
(which is a public API method) has been called.
|
||||
|
||||
See the [plugin development](/docs/html/plugin_development.html)
|
||||
section for more info on writing plugins.
|
||||
|
||||
Inside a plugin, you can get access to the {@link _converse.api}
|
||||
object. Note the underscore in front of {@link _converse},
|
||||
which indicates that this is a private, closured object.
|
||||
|
||||
## API Namespaces
|
||||
|
||||
The Converse API (private and public) makes use of namespaces to logically
|
||||
group relevant methods.
|
||||
|
||||
So, for example, all the XEP-0030 service discovery methods are under the
|
||||
{@link \_converse.api.disco} namespace, in the [private API]{@link \_converse.api}.
|
||||
|
||||
Which means that you access it via {@link _converse.api.disco}.
|
||||
|
||||
### Nested Namespaces
|
||||
|
||||
Namespaces can be nested.
|
||||
|
||||
{@link _converse.api} is the top-level namespace, of which {@link \_converse.api.disco}
|
||||
is a nested, child namespace and {@link \_converse.api.disco.own} is nested another
|
||||
level deeper.
|
||||
|
||||
Not all methods are however within a namespace. For example {@link converse.initialize}.
|
||||
|
||||
## Stable API versus unstable API
|
||||
|
||||
Converse uses [semantic versioning](https://semver.org/) for releases, which means that
|
||||
we try to maintain a stable API for minor and patch releases and when we do change the
|
||||
stable API we will make a major release.
|
||||
|
||||
In the JSDoc API documentation, all API methods that are **not** marked as *Private*
|
||||
are considered to be part of the stable API, and you can therefore expect them to
|
||||
not change between minor and patch releases. If a method is marked as *Private*,
|
||||
then you could still use it, but we don't provide any guarantee that it won't change
|
||||
between minor and patch releases.
|
@ -1,140 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/other_frameworks.rst">Edit me on GitHub</a></div>
|
||||
|
||||
Integrating converse.js into other frameworks
|
||||
=============================================
|
||||
|
||||
Angular.js
|
||||
----------
|
||||
|
||||
Angular.js has the concept of a `service <https://docs.angularjs.org/guide/services#!>`_,
|
||||
which is a special kind of `provider <https://docs.angularjs.org/guide/providers>`_.
|
||||
|
||||
An angular.js service is a constructor or object which provides an API defined by the
|
||||
author of the service. The goal of a service is to organize and share code, so
|
||||
that it can be used across an application.
|
||||
|
||||
So, if we wanted to properly integrate converse.js into an angular.js
|
||||
application, then putting it into a service is a good approach.
|
||||
|
||||
This lets us avoid having a global ``converse`` API object (accessible via
|
||||
``windows.converse``), and instead we can get hold of the converse API via
|
||||
angular's dependency injection when we specify it as a dependency for our
|
||||
angular components.
|
||||
|
||||
Below is an example code that wraps converse.js as an angular.js service.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
angular.module('converse', []).service('converse', function() {
|
||||
// We create three promises, which will be resolved at various times
|
||||
var loaded_deferred = new $.Deferred(),
|
||||
connected_deferred = new $.Deferred();
|
||||
|
||||
var service = {
|
||||
'waitUntilLoaded': _.constant(loaded_deferred.promise()),
|
||||
'initialize': function initConverse(options) {
|
||||
this.waitUntilLoaded().done(_.partial(this.api.initialize, options));
|
||||
},
|
||||
'waitUntilConnected': _.constant(connected_deferred.promise())
|
||||
};
|
||||
|
||||
// Here we define the core components of converse.js that will be
|
||||
// loaded and used.
|
||||
define([
|
||||
"converse-core",
|
||||
// START: Removable components
|
||||
// --------------------
|
||||
// Any of the following components may be removed if they're not needed.
|
||||
"locales", // Translations for converse.js. This line can be removed
|
||||
// to remove *all* translations, or you can modify the
|
||||
// file src/locales.js to include only those
|
||||
// translations that you care about.
|
||||
|
||||
"converse-chatview", // Renders standalone chatboxes for single user chat
|
||||
"converse-controlbox", // The control box
|
||||
"converse-bookmarks", // XEP-0048 Bookmarks
|
||||
"converse-mam", // XEP-0313 Message Archive Management
|
||||
"converse-muc", // XEP-0045 Multi-user chat
|
||||
"converse-vcard", // XEP-0054 VCard-temp
|
||||
"converse-register", // XEP-0077 In-band registration
|
||||
"converse-ping", // XEP-0199 XMPP Ping
|
||||
"converse-notification", // HTML5 Notifications
|
||||
"converse-minimize", // Allows chatboxes to be minimized
|
||||
"converse-dragresize", // Allows chatboxes to be resized by dragging them
|
||||
"converse-headline", // Support for headline messages
|
||||
// END: Removable components
|
||||
|
||||
], function(converse) {
|
||||
service.api = converse;
|
||||
|
||||
// Register a plugin which resolves `waitUntilConnected` promise.
|
||||
converse.plugins.add('conversejs-angular-service', {
|
||||
initialize: function () {
|
||||
this._converse.api.listen.on('connected', connected_deferred.resolve);
|
||||
}
|
||||
});
|
||||
|
||||
// Converse.js has been loaded, so we can resolve the `waitUntilLoaded` promise.
|
||||
return loaded_deferred.resolve();
|
||||
});
|
||||
require(["converse"]);
|
||||
return service;
|
||||
});
|
||||
|
||||
The above code is a modified version of the file `src/converse.js <https://github.com/jcbrand/converse.js/blob/master/src/converse.js>`_
|
||||
which defines the converse AMD module and specifies which plugins will go into
|
||||
this build.
|
||||
|
||||
You should replace the contents of that file with the above, if you want such a
|
||||
service registered. Then, you should run `make build`, to create new build
|
||||
files in the `dist` directory, containing your new angular.js service.
|
||||
|
||||
The above code registers an angular.js module and service, both named ``converse``.
|
||||
|
||||
This module should then be added as a dependency for your own angular.js
|
||||
modules, for example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
angular.module('my-module', ['converse']);
|
||||
|
||||
Then you can have the converse service dependency injected into
|
||||
your components, for example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
angular.module('my-module').provider('my-provider', function(converse) {
|
||||
// Your custom code can come here..
|
||||
|
||||
// Then when you're ready, you can initialize converse.js
|
||||
converse.waitUntilLoaded().done(function () {
|
||||
converse.initialize({
|
||||
'allow_logout': false,
|
||||
'auto_login': 'true',
|
||||
'auto_reconnect': true,
|
||||
'bosh_service_url': bosh_url,
|
||||
'jid': bare_jid,
|
||||
'credentials_url': credentials_url,
|
||||
'whitelisted_plugins': ['conversejs-angular-service']
|
||||
});
|
||||
|
||||
// More custom code could come here...
|
||||
});
|
||||
});
|
||||
|
||||
You might have noticed the ``waitUntilLoaded()`` method being called on the ``converse``
|
||||
service. This is a special method added to the service (see the implementation
|
||||
example above) that makes sure that converse.js is loaded and available. It
|
||||
returns a promise which resolves once converse.js is available.
|
||||
|
||||
This is necessary because with otherwise you might run into race-conditions
|
||||
when your angular application loads more quickly then converse.js.
|
||||
|
||||
Lastly, the API of converse is available via the ``.api`` attribute on the service.
|
||||
So you can call it like this for example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.api.user.status.set('online');
|
@ -1,640 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/plugin_development.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`writing-a-plugin`:
|
||||
|
||||
Writing a plugin
|
||||
================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Converse.js has a plugin architecture based on `pluggable.js <https://github.com/jcbrand/pluggable.js/>`_
|
||||
and is itself composed out of plugins.
|
||||
|
||||
There are only a few files that are included in the default build of Converse
|
||||
which aren't plugins.
|
||||
|
||||
An important one is `core.js <https://github.com/conversejs/.js/blob/master/src/headless/core.js>`_,
|
||||
which is responsible for bootstrapping the plugin architecture,
|
||||
setting up and maintaining the connection to the XMPP
|
||||
server and declaring the public (`window.converse </docs/html/api/converse.html>`_) and protected (`_converse.api </docs/html/api/-_converse.api.html>`_) APIs.
|
||||
|
||||
The other non-plugin files all contain utility methods in
|
||||
`src/utils <https://github.com/conversejs/converse.js/blob/master/src/utils>`_ and
|
||||
`src/headless/utils <https://github.com/conversejs/converse.js/blob/master/src/headless/utils>`_.
|
||||
|
||||
As a general rule, any file in the ``./src`` directory that starts with
|
||||
``converse-`` is a plugin (with the exception of ``converse-core.js``.
|
||||
|
||||
The plugin architecture lets you add new features or modify existing functionality in a
|
||||
modular and self-contained way, without having to change other files.
|
||||
|
||||
This ensures that plugins are fully optional (one of the design goals of
|
||||
Converse) and can be removed from the main build without breaking the app.
|
||||
For example, the ``converse-omemo``,
|
||||
``converse-rosterview``, ``converse-dragresize``, ``converse-minimize``,
|
||||
``converse-muc`` and ``converse-muc-views`` plugins can all be removed from the
|
||||
build without breaking the app.
|
||||
|
||||
To more deeply understand how the plugin architecture works, read the
|
||||
`pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
|
||||
and to understand its inner workings, refer to the `annotated source code
|
||||
<https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
|
||||
|
||||
Advantages of plugins
|
||||
---------------------
|
||||
|
||||
Writing a plugin is the recommended way to customize or add new features to Converse.
|
||||
|
||||
The main benefit of plugins is that they allow for **isolation of concerns** (and features).
|
||||
From this benefit flows various 2nd order advantages, such as the ability to
|
||||
make smaller production builds (by excluding unused plugins) and an easier
|
||||
upgrade path by avoiding touching Converse's internals.
|
||||
|
||||
Plugins are especially useful if you want to add proprietary modifications, since the
|
||||
Mozilla Public License version 2 doesn't require you to open source your
|
||||
plugin files. Be aware that this doesn't apply when you intend to use libsignal for
|
||||
OMEMO encryption because libsignal's license is GPLv3 (and turns the entire app
|
||||
into a GPLv3 app).
|
||||
|
||||
Each plugin comes in its own file, and Converse's plugin architecture,
|
||||
`pluggable.js <https://github.com/jcbrand/pluggable.js/>`_, provides you
|
||||
with the ability to "hook in" to the core code and other plugins.
|
||||
|
||||
Plugins enable developers to extend and override existing objects,
|
||||
functions and the models and views that make up
|
||||
Converse. You can also create new models and views.
|
||||
|
||||
.. note:: **Trying out a plugin in JSFiddle**
|
||||
|
||||
Because Converse consists only of JavaScript, HTML and CSS (with no backend
|
||||
code required like PHP, Python or Ruby) it runs fine in JSFiddle.
|
||||
|
||||
Here's a Fiddle with a Converse plugin that calls ``alert`` once it gets
|
||||
initialized and also when a chat message gets rendered: https://jsfiddle.net/4drfaok0/15/
|
||||
|
||||
|
||||
.. note:: **Generating a plugin with Yeoman**
|
||||
|
||||
The rest of this document explains how to write a plugin for Converse and
|
||||
ends with a documented example of a plugin.
|
||||
|
||||
There is a `Yeoman <http://yeoman.io/>`_ code generator, called
|
||||
`generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_, which
|
||||
you can use to generate plugin scaffolding/boilerplate that serves as a
|
||||
starting point and basis for writing your plugin.
|
||||
|
||||
Please refer to the `generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_
|
||||
README for information on how to use it.
|
||||
|
||||
Registering a plugin
|
||||
--------------------
|
||||
|
||||
Plugins need to be registered (and whitelisted) before they can be loaded and
|
||||
initialized.
|
||||
|
||||
You register a Converse plugin by calling ``converse.plugins.add``.
|
||||
|
||||
The plugin itself is a JavaScript object which usually has at least an
|
||||
``initialize`` method, which gets called at the end of the
|
||||
``converse.initialize`` method which is the top-level method that gets called
|
||||
by the website to configure and initialize Converse itself.
|
||||
|
||||
Here's an example code snippet:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.plugins.add('myplugin', {
|
||||
|
||||
initialize: function () {
|
||||
// This method gets called once converse.initialize has been called
|
||||
// and the plugin itself has been loaded.
|
||||
|
||||
// Inside this method, you have access to the closured
|
||||
// _converse object as an attribute on "this".
|
||||
// E.g. this._converse
|
||||
},
|
||||
});
|
||||
|
||||
.. note:: It's important that `converse.plugins.add` is called **before**
|
||||
`converse.initialize` is called. Otherwise the plugin will never get
|
||||
registered and never get called.
|
||||
|
||||
Whitelisting of plugins
|
||||
-----------------------
|
||||
|
||||
As of Converse 3.0.0 and higher, plugins need to be whitelisted before they
|
||||
can be used. This is because plugins have access to a powerful API. For
|
||||
example, they can read all messages and send messages on the user's behalf.
|
||||
|
||||
To avoid malicious plugins being registered (i.e. by malware infected
|
||||
advertising networks) we now require whitelisting.
|
||||
|
||||
To whitelist a plugin simply means to specify :ref:`whitelisted_plugins` when
|
||||
you call ``converse.initialize``.
|
||||
|
||||
If you're adding a "core" plugin, which means a plugin that will be
|
||||
included in the default, open-source version of Converse, then you'll
|
||||
instead whitelist the plugin by adding its name to the `core_plugins` array in
|
||||
`./src/headless/converse-core.js <https://github.com/jcbrand/converse.js/blob/master/src/headless/converse-core.js>`_.
|
||||
or the `WHITELISTED_PLUGINS` array in `./src/converse.js <https://github.com/jcbrand/converse.js/blob/master/src/converse.js>`_.
|
||||
|
||||
Where you add it depends on whether your plugin is part of the headless build
|
||||
(which means it doesn't contain any view code) or not.
|
||||
|
||||
Security and access to the inner workings
|
||||
-----------------------------------------
|
||||
|
||||
The globally available ``converse`` object, which exposes the API methods, such
|
||||
as ``initialize`` and ``plugins.add``, is a wrapper that encloses and protects
|
||||
a sensitive inner object, named ``_converse`` (not the underscore prefix).
|
||||
|
||||
This inner ``_converse`` object contains all the models and views,
|
||||
as well as various other attributes and functions.
|
||||
|
||||
Within a plugin, you will have access to this internal
|
||||
`"closured" <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures>`_
|
||||
``_converse`` object, which is normally not exposed in the global variable scope.
|
||||
|
||||
The inner ``_converse`` object is made private in order to safely hide and
|
||||
encapsulate sensitive information and methods which should not be exposed
|
||||
to any 3rd-party scripts that might be running in the same page.
|
||||
|
||||
|
||||
Accessing 3rd party libraries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Immediately inside the module shown above you can access 3rd party libraries (such
|
||||
dayjs) via the ``converse.env`` map.
|
||||
|
||||
The code for it could look something like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
// Commonly used utilities and variables can be found under the "env"
|
||||
// namespace of the "converse" global.
|
||||
const { Promise, Strophe, dayjs, sizzle, $build, $iq, $msg, $pres } = converse.env;
|
||||
|
||||
These dependencies are closured so that they don't pollute the global
|
||||
namespace, that's why you need to access them in such a way inside the module.
|
||||
|
||||
Overriding templates
|
||||
--------------------
|
||||
|
||||
Converse uses `lit-html <https://lit-html.polymer-project.org/guide>`_
|
||||
templates and templates are imported as separate files.
|
||||
|
||||
It's possible to configure your module bundler (e.g. Webpack) in such as way that a
|
||||
different file is loaded when a template is imported.
|
||||
|
||||
This allows you to create your own templates that are used instead of the ones
|
||||
that would have originally been imported.
|
||||
|
||||
With Webpack (which Converse uses internally), you can specify an
|
||||
``alias`` for the template you want to override. This alias then points to your
|
||||
own custom template.
|
||||
|
||||
For example, in your webpack config file, you could add the following to the
|
||||
``config`` object that gets exported:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
modules: [
|
||||
path.join(__dirname, 'node_modules'),
|
||||
path.join(__dirname, 'node_modules/converse.js/src')
|
||||
],
|
||||
alias: {
|
||||
'plugins/profile/templates/profile.js$': path.resolve(__dirname, 'templates/custom-profile.js')
|
||||
}
|
||||
}
|
||||
|
||||
This will override the template that gets imported at the path ``plugins/profile/templates/profile.js``
|
||||
with your own template at the path ``templates/custom-profile.js`` (relative to your webpack config file).
|
||||
|
||||
|
||||
Object and class Overrides
|
||||
--------------------------
|
||||
|
||||
.. note:: Using the `overrides` feature from pluggable.js is discouraged. It's
|
||||
much better to use events, promises and `hooks`_ to modify the behaviour of
|
||||
Converse.
|
||||
|
||||
The pluggable.js `overrides` will only work on objects and classes that are
|
||||
set as attributes on the `_converse` object, which doesn't apply to many
|
||||
newer classes and objects, such as the web components. For these clasess,
|
||||
overrides won't work at all.
|
||||
|
||||
This section is left here for completeness, because in some special cases
|
||||
overrides are still used.
|
||||
|
||||
Plugins can override core code or code from other plugins. You can specify
|
||||
overrides in the object passed to ``converse.plugins.add``.
|
||||
|
||||
In an override you can still call the overridden function, by calling
|
||||
``this.__super__.methodName.apply(this, arguments);`` where ``methodName`` is
|
||||
the name of the function or method you're overriding.
|
||||
|
||||
The following code snippet provides an example of two different overrides:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
overrides: {
|
||||
/* The *_converse* object has a method "onConnected".
|
||||
* You can override that method as follows:
|
||||
*/
|
||||
onConnected: function () {
|
||||
// Overrides the onConnected method in Converse
|
||||
|
||||
// Top-level functions in "overrides" are bound to the
|
||||
// inner "_converse" object.
|
||||
const _converse = this;
|
||||
|
||||
// Your custom code can come here ...
|
||||
|
||||
// You can access the original function being overridden
|
||||
// via the __super__ attribute.
|
||||
// Make sure to pass on the arguments supplied to this
|
||||
// function and also to apply the proper "this" object.
|
||||
_converse.__super__.onConnected.apply(this, arguments);
|
||||
|
||||
// Your custom code can come here ...
|
||||
},
|
||||
|
||||
/* On the XMPPStatus model is a method sendPresence.
|
||||
* We can override is as follows:
|
||||
*/
|
||||
XMPPStatus: {
|
||||
sendPresence: function (type, status_message, jid) {
|
||||
// The "_converse" object is available via the __super__
|
||||
// attribute.
|
||||
const _converse = this.__super__._converse;
|
||||
|
||||
// Custom code can come here ...
|
||||
|
||||
// You can call the original overridden method, by
|
||||
// accessing it via the __super__ attribute.
|
||||
// When calling it, you need to apply the proper
|
||||
// context as reference by the "this" variable.
|
||||
this.__super__.sendPresence.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Use the ``overrides`` feature with caution. It basically resorts to
|
||||
monkey patching which pollutes the call stack and can make your code fragile
|
||||
and prone to bugs when Converse gets updated. Too much use of ``overrides``
|
||||
is therefore a "code smell" which should ideally be avoided.
|
||||
|
||||
A better approach is to use the events and `hooks`_ emitted by Converse, and to add
|
||||
your code in event handlers. This is however not always possible, in which case
|
||||
the overrides are a powerful tool.
|
||||
|
||||
Also, while it's possible to add new methods to classes via the ``overrides``
|
||||
feature, it's better and more explicit to use composition with
|
||||
``Object.assign``.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
function doSomething () {
|
||||
// Your code comes here
|
||||
}
|
||||
Object.assign(_converse.ChatBoxView.prototype, { doSomething });
|
||||
|
||||
|
||||
|
||||
.. _`dependencies`:
|
||||
|
||||
Plugin dependencies
|
||||
-------------------
|
||||
|
||||
When using ``overrides``, the code that you want to override (which is either
|
||||
in ``converse-core`` or in other plugins), needs to be parsed already by the
|
||||
time your ``overrides`` are being parsed.
|
||||
|
||||
Additionally, when you register event or promise handlers in your plugin for
|
||||
events/promises that fire in other plugins, then you want those plugins to have
|
||||
been loaded before your plugin gets loaded.
|
||||
|
||||
To resolve this problem we have the ``dependencies`` Array attribute.
|
||||
With this you can specify those dependencies which need to be loaded before
|
||||
your plugin is loaded.
|
||||
|
||||
In some cases, you might want to depend on another plugin if it's available,
|
||||
but don't care when it's not available.
|
||||
An example is the `converse-dragresize <https://github.com/jcbrand/converse.js/blob/master/src/converse-dragresize.js>`_
|
||||
plugin, which will add drag-resize handles to the headlines box (which shows
|
||||
messages of type ``headline``) but doesn't care when that particular plugin is
|
||||
not available.
|
||||
|
||||
If the :ref:`strict_plugin_dependencies` setting is set to ``false`` (which is
|
||||
its default value), then no error will be raised if the plugin is not found.
|
||||
|
||||
In this case, you can't specify the plugin as a dependency in the ``define``
|
||||
statement at the top of the plugin, since it might not always be available,
|
||||
which would cause ``require.js`` to throw an error.
|
||||
|
||||
Extending Converse's configuration settings
|
||||
----------------------------------------------
|
||||
|
||||
Converse comes with various :ref:`configuration-settings` that can be used to
|
||||
modify its functionality and behavior.
|
||||
|
||||
All configuration settings have default values which can be overridden when
|
||||
`converse.initialize` (see `converse.initialize </docs/html/api/converse.html#.initialize>`_)
|
||||
gets called.
|
||||
|
||||
Plugins often need their own additional configuration settings and you can add
|
||||
these settings with the `_converse.api.settings.update </docs/html/api/-_converse.api.settings.html#.update>`_
|
||||
method.
|
||||
|
||||
Exposing promises
|
||||
-----------------
|
||||
|
||||
Converse has a `waitUntil </docs/html/api/-_converse.api.html#.waitUntil>`_ API method
|
||||
which allows you to wait for various promises to resolve before executing a
|
||||
piece of code.
|
||||
|
||||
You can add new promises for your plugin by calling
|
||||
`_converse.api.promises.add </docs/html/api/-_converse.api.promises.html#.add>`_.
|
||||
|
||||
Generally, your plugin will then also be responsible for making sure these
|
||||
promises are resolved. You do this by calling
|
||||
`_converse.api.trigger </docs/html/api/-_converse.api.html#.trigger>`_, which not
|
||||
only resolves the plugin but will also emit an event with the same name.
|
||||
|
||||
Dealing with asynchronicity
|
||||
---------------------------
|
||||
|
||||
Due to the asynchronous nature of XMPP, many subroutines in Converse execute
|
||||
at different times and not necessarily in the same order.
|
||||
|
||||
In many cases, when you want to execute a piece of code in a plugin, you first
|
||||
want to make sure that the supporting data-structures that your code might rely
|
||||
on have been created and populated with data.
|
||||
|
||||
There are two ways of waiting for the right time before executing your code.
|
||||
You can either listen for certain events, or you can wait for promises to
|
||||
resolve.
|
||||
|
||||
For example, when you want to query the message archive between you and a
|
||||
friend, you would call ``this._converse.api.archive.query({'with': 'friend@example.org'});``
|
||||
|
||||
However, simply calling this immediately in the ``initialize`` method of your plugin will
|
||||
not work, since the user is not logged in yet.
|
||||
|
||||
In this case, you should first listen for the ``connection`` event, and then do your query, like so:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.plugins.add('myplugin', {
|
||||
initialize: function () {
|
||||
const _converse = this._converse;
|
||||
|
||||
_converse.api.listen.on('connected', function () {
|
||||
_converse.api.archive.query({'with': 'admin2@localhost'});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Another example is in the ``Bookmarks`` plugin (in
|
||||
`src/converse-bookmarks.js <https://github.com/jcbrand/converse.js/blob/6c3aa34c23d97d679823a64376418cd0f40a8b94/src/converse-bookmarks.js#L528>`_).
|
||||
Before bookmarks can be fetched and shown to the user, we first have to wait until
|
||||
the `"Rooms"` panel of the ``ControlBox`` has been rendered and inserted into
|
||||
the DOM. Otherwise we have no place to show the bookmarks yet.
|
||||
|
||||
Therefore, there are the following lines of code in the ``initialize`` method of
|
||||
`converse-bookmarks.js <https://github.com/jcbrand/converse.js/blob/6c3aa34c23d97d679823a64376418cd0f40a8b94/src/converse-bookmarks.js#L528>`_:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
Promise.all([
|
||||
_converse.api.waitUntil('chatBoxesFetched'),
|
||||
_converse.api.waitUntil('roomsPanelRendered')
|
||||
]).then(initBookmarks);
|
||||
|
||||
What this means, is that the plugin will wait until the ``chatBoxesFetched``
|
||||
and ``roomsPanelRendered`` promises have been resolved before it calls the
|
||||
``initBookmarks`` method (which is defined inside the plugin).
|
||||
|
||||
This way, we know that we have everything in place and set up correctly before
|
||||
fetching the bookmarks.
|
||||
|
||||
As yet another example, there is also the following code in the ``initialize``
|
||||
method of the plugin:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
_converse.api.listen.on('chatBoxOpened', function renderMinimizeButton (view) {
|
||||
// Inserts a "minimize" button in the chatview's header
|
||||
|
||||
// Implementation code removed for brevity
|
||||
// ...
|
||||
});
|
||||
|
||||
In this case, the plugin waits for the ``chatBoxOpened`` event, before it then
|
||||
calls ``renderMinimizeButton``, which adds a new button to the chatbox (which
|
||||
enables you to minimize it).
|
||||
|
||||
Finding the right promises and/or events to listen to, can be a bit
|
||||
challenging, and sometimes it might be necessary to create new events or
|
||||
promises.
|
||||
|
||||
Please refer to the `API documentation </docs/html/api/http://localhost:8008/docs/html/api/>`_
|
||||
for an overview of what's available to you. If you need new events or promises, then
|
||||
`please open an issue or make a pull request on Github <https://github.com/jcbrand/converse.js>`_
|
||||
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
Converse has the concept of ``hooks``, which are special events that allow you
|
||||
to modify it's behaviour at runtime.
|
||||
|
||||
A hook is similar to an event, but it differs in two meaningful ways:
|
||||
|
||||
1. Converse will wait for all handlers of a hook to finish before continuing inside the function from where the hook was triggered.
|
||||
2. Each hook contains a payload, which the handlers can modify or extend, before returning it (either to the function that triggered the hook or to subsequent handlers).
|
||||
|
||||
These two properties of hooks makes it possible for 3rd party plugins to
|
||||
intercept and update data, allowing them to modify Converse without the need of
|
||||
resorting to `overrides`_.
|
||||
|
||||
A hook is triggered in the following way:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
async function hookTriggerExample () {
|
||||
const payload = { foo: 'bar' };
|
||||
const updated_payload = await api.hook('hookName', this, payload);
|
||||
return updated_payload;
|
||||
}
|
||||
|
||||
The above could be shortened:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
async function hookTriggerExample () {
|
||||
return await api.hook('hookName', this, { foo: 'bar' });
|
||||
}
|
||||
|
||||
The ``async/await`` syntax could also be removed, but then it's less clear to
|
||||
the reader that this function returns a promise.
|
||||
|
||||
Let's assume that in a plugin somewhere a listener is registered for this hook:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
function hookListenerExample () {
|
||||
|
||||
api.listen.on('hookname', (context, payload) => {
|
||||
return {...payload, 'baz': 'buzz'};
|
||||
});
|
||||
}
|
||||
|
||||
The ``context`` parameter in our listener is usually the ``this`` of the function
|
||||
that triggered the hook (as is the case in ``hookTriggerExample``),
|
||||
but could also be a ``Model`` instance.
|
||||
|
||||
The ``payload`` parameter is the same payload that was passed in in
|
||||
``hookTriggerExample``.
|
||||
|
||||
The ``hookListenerExample`` function accepts the payload and returns a new one
|
||||
which contains the original payload together with a new key and value.
|
||||
|
||||
The ``updated_payload`` that is now returned from ``hookTriggerExample`` looks
|
||||
as follows:
|
||||
|
||||
::
|
||||
|
||||
{ foo: 'bar', bazz: 'buzz' }
|
||||
|
||||
Our plugin was able to add data to the payload without requiring any kind of
|
||||
knowledge from ``hookTriggerExample`` about ``hookListenerExample`` and
|
||||
without any kind of coupling betwee the code.
|
||||
|
||||
A good example of a real-world hook in Converse, is the
|
||||
`getMessageActionButtons <https://conversejs.org/docs/html/api/-_converse.html#event:getMessageActionButtons>`_
|
||||
which allows you to add, modify or delete the actions you can take on a message
|
||||
in a chat.
|
||||
|
||||
The `Actions <https://github.com/conversejs/community-plugins/tree/master/packages/actions>`_
|
||||
3rd party community plugin makes use of this hook to add extra actions such as
|
||||
``like`` or ``dislike`` to chat messages.
|
||||
|
||||
|
||||
An example plugin
|
||||
-----------------
|
||||
|
||||
Below follows a documented example of a plugin. This is the same code that gets
|
||||
generated by `generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
import converse from "@converse/headless/converse-core";
|
||||
|
||||
// Commonly used utilities and variables can be found under the "env"
|
||||
// namespace of the "converse" global.
|
||||
const { Promise, Strophe, dayjs, sizzle, _, $build, $iq, $msg, $pres } = converse.env;
|
||||
|
||||
// The following line registers your plugin.
|
||||
converse.plugins.add("myplugin", {
|
||||
|
||||
/* Dependencies are other plugins which might be
|
||||
* overridden or relied upon, and therefore need to be loaded before
|
||||
* this plugin. They are "optional" because they might not be
|
||||
* available, in which case any overrides applicable to them will be
|
||||
* ignored.
|
||||
*
|
||||
* NB: These plugins need to have already been imported or loaded,
|
||||
* either in your plugin or somewhere else.
|
||||
*
|
||||
* It's possible to make these dependencies "non-optional".
|
||||
* If the setting "strict_plugin_dependencies" is set to true,
|
||||
* an error will be raised if the plugin is not found.
|
||||
*/
|
||||
dependencies: [],
|
||||
|
||||
/* Converse's plugin mechanism will call the initialize
|
||||
* method on any plugin (if it exists) as soon as the plugin has
|
||||
* been loaded.
|
||||
*/
|
||||
initialize: function () {
|
||||
/* Inside this method, you have access to the private
|
||||
* `_converse` object.
|
||||
*/
|
||||
const _converse = this._converse;
|
||||
_converse.log("The \"myplugin\" plugin is being initialized");
|
||||
|
||||
/* From the `_converse` object you can get any configuration
|
||||
* options that the user might have passed in via
|
||||
* `converse.initialize`.
|
||||
*
|
||||
* You can also specify new configuration settings for this
|
||||
* plugin, or override the default values of existing
|
||||
* configuration settings. This is done like so:
|
||||
*/
|
||||
_converse.api.settings.update({
|
||||
'initialize_message': 'Initializing myplugin!'
|
||||
});
|
||||
|
||||
/* The user can then pass in values for the configuration
|
||||
* settings when `converse.initialize` gets called.
|
||||
* For example:
|
||||
*
|
||||
* converse.initialize({
|
||||
* "initialize_message": "My plugin has been initialized"
|
||||
* });
|
||||
*/
|
||||
alert(this._converse.initialize_message);
|
||||
|
||||
/* Besides `_converse.api.settings.update`, there is also a
|
||||
* `_converse.api.promises.add` method, which allows you to
|
||||
* add new promises that your plugin is obligated to fulfill.
|
||||
*
|
||||
* This method takes a string or a list of strings which
|
||||
* represent the promise names:
|
||||
*
|
||||
* _converse.api.promises.add('myPromise');
|
||||
*
|
||||
* Your plugin should then, when appropriate, resolve the
|
||||
* promise by calling `_converse.api.trigger`, which will also
|
||||
* trigger an event with the same name as the promise.
|
||||
* For example:
|
||||
*
|
||||
* _converse.api.trigger('operationCompleted');
|
||||
*
|
||||
* Other plugins can then either listen for the event
|
||||
* `operationCompleted` like so:
|
||||
*
|
||||
* _converse.api.listen.on('operationCompleted', function { ... });
|
||||
*
|
||||
* or they can wait for the promise to be fulfilled like so:
|
||||
*
|
||||
* _converse.api.waitUntil('operationCompleted', function { ... });
|
||||
*/
|
||||
|
||||
|
||||
/* In your plugin, you can also listen for hooks.
|
||||
* Hooks allow you to add or modify data and properties used by
|
||||
* Converse.
|
||||
*
|
||||
* For example, the getToolbarButtons hook allows you to add new buttons to the chat toolbar.
|
||||
* https://conversejs.org/docs/html/api/-_converse.html#event:getToolbarButtons
|
||||
*/
|
||||
api.listen.on('getToolbarButtons', (toolbar_el, buttons) => {
|
||||
buttons.push(html`
|
||||
<button class="my-button" @click=${alert('hello world!')}>
|
||||
<converse-icon class="fa fa-eye" size="1em" color="blue"></converse-icon>
|
||||
</button>
|
||||
`);
|
||||
return buttons;
|
||||
});
|
||||
}
|
||||
});
|
@ -1,159 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/quickstart.rst">Edit me on GitHub</a></div>
|
||||
|
||||
==========
|
||||
Quickstart
|
||||
==========
|
||||
|
||||
Getting a demo up and running
|
||||
=============================
|
||||
|
||||
You can try out the latest version of Converse at `conversejs.org <https://conversejs.org>`_
|
||||
for the overlayed version and `conversejs.org/fullscreen.html <https://conversejs.org/fullscreen.html>`_
|
||||
for the full page version.
|
||||
|
||||
If you want to host and serve Converse yourself, there are a few options available.
|
||||
|
||||
Let your XMPP server serve Converse for you
|
||||
-------------------------------------------
|
||||
|
||||
If you run your own XMPP server, you might first want to check whether it has
|
||||
a plugin or module for hosting Converse.
|
||||
|
||||
* `Openfire <http://www.igniterealtime.org/projects/openfire/>`_ has the `inverse <https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=inverse>`_ plugin.
|
||||
* `Prosody <https://prosody.im/>`_ has `mod_conversejs <https://modules.prosody.im/mod_conversejs.html>`_.
|
||||
* `ejabberd <http://www.ejabberd.im/>`_ has `mod_conversejs <https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs>`_.
|
||||
|
||||
|
||||
Serving Converse yourself
|
||||
-------------------------
|
||||
|
||||
Alternative you can serve only Converse without requiring any particular XMPP server.
|
||||
|
||||
To do so, you'll need to get the right files to host, for which you have four options.
|
||||
|
||||
.. note::
|
||||
|
||||
Pro-tip, if you just want to quickly test things locally, you can run ``make serve`` inside a checkout of the Converse repo.
|
||||
Converse is then hosted at http://localhost:8000
|
||||
|
||||
|
||||
Option 1: Use the content delivery network
|
||||
******************************************
|
||||
|
||||
Converse has a `CDN <https://en.wikipedia.org/wiki/Content_delivery_network>`_, provided by `KeyCDN <http://keycdn.com/>`_,
|
||||
which hosts its JavaScript and CSS files.
|
||||
|
||||
The latest versions of these files are available at these URLs:
|
||||
|
||||
* https://cdn.conversejs.org/dist/converse.min.js
|
||||
* https://cdn.conversejs.org/dist/converse.min.css
|
||||
|
||||
If you are integrating Converse into an existing website or app, then we recommend
|
||||
that you load a specific version of Converse. Otherwise your website or app
|
||||
might break when a new backwards-incompatible version of Converse is released.
|
||||
|
||||
To load a specific version of Converse you can put the version in the URL:
|
||||
|
||||
* https://cdn.conversejs.org/10.1.6/dist/converse.min.js
|
||||
* https://cdn.conversejs.org/10.1.6/dist/converse.min.css
|
||||
|
||||
You can include these two URLs inside the *<head>* element of your website
|
||||
via the *script* and *link* tags:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/10.1.6/dist/converse.min.css">
|
||||
<script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js" charset="utf-8"></script>
|
||||
|
||||
|
||||
Option 2: Download the builds from Github
|
||||
*****************************************
|
||||
|
||||
The `Converse releases page on Github <https://github.com/conversejs/converse.js/releases>`_
|
||||
has the release notes for every release as well as links to downloadable zip files
|
||||
containing all the files you need to host Converse yourself.
|
||||
|
||||
Extract the zip file and include converse.min.js and converse.min.css files in
|
||||
the *<head>* element of your page, similar as shown in option 1 above.
|
||||
|
||||
|
||||
Option 3: Building the files yourself
|
||||
*************************************
|
||||
|
||||
Instead of using the CDN, you can also create your own builds and host them yourself.
|
||||
|
||||
Have a look at the :ref:`creating_builds` section on how to create your own builds.
|
||||
|
||||
In short, you should be able to do it by running ``make dist`` inside a
|
||||
checkout of the `Converse repo <http://github.com/conversejs/converse.js/>`_.
|
||||
|
||||
To build the files and also start an HTTP server, you can run ``make serve``.
|
||||
|
||||
The distribution files will be added to the ``./dist`` folder inside the repo.
|
||||
|
||||
|
||||
Initializing Converse
|
||||
=====================
|
||||
|
||||
You'll need to initialize Converse with configuration settings relevant to your requirements.
|
||||
Take a look at the :ref:`configuration-settings` section for info on all the available settings.
|
||||
|
||||
To quickly get started, you can put the following JavaScript code at the
|
||||
bottom of your page (after the closing *</body>* element)::
|
||||
|
||||
<script>
|
||||
converse.initialize({
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||
show_controlbox_by_default: true
|
||||
});
|
||||
</script>
|
||||
|
||||
The `index.html <https://github.com/jcbrand/converse.js/blob/master/index.html>`_ file inside the
|
||||
Converse repository serves as a nice, usable example.
|
||||
|
||||
Fullscreen version
|
||||
------------------
|
||||
|
||||
Converse also comes in a fullscreen version.
|
||||
A hosted version is available online at `conversejs.org/fullscreen <https://conversejs.org/fullscreen.html>`_.
|
||||
|
||||
Originally this version was available as a separate build file, but
|
||||
as of version 4.0.0 and higher, the difference between the "overlay" and the
|
||||
"fullscreen" versions of converse.js is simply a matter of configuring the
|
||||
:ref:`view_mode`.
|
||||
|
||||
For example::
|
||||
|
||||
<script>
|
||||
converse.initialize({
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||
view_mode: 'fullscreen'
|
||||
});
|
||||
</script>
|
||||
|
||||
Where to go from here?
|
||||
======================
|
||||
|
||||
Have a look at the various :ref:`features <features>` that Converse provides, for some of
|
||||
them you might have to do more setup work, like configuring an XMPP server or
|
||||
webserver.
|
||||
|
||||
You might want to implement some kind of persistent single-session solution for
|
||||
your website, where users authenticate once in your website and are then
|
||||
automatically logged in to the XMPP server as well. For more info on how this
|
||||
can be achieved, read: :ref:`session-support`.
|
||||
|
||||
For end-to-end encryption via OMEMO, you'll need to load `libsignal-protocol.js
|
||||
<https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in
|
||||
your page. Take a look at the section on :ref:`libsignal <dependency-libsignal>` and the
|
||||
:ref:`security considerations around OMEMO <feature-omemo>`.
|
||||
|
||||
Perhaps you want to create your own custom build of Converse? Then head over
|
||||
to the :doc:`builds` section, or more generally the :doc:`development <development>`
|
||||
documentation.
|
||||
|
||||
Do you want to know how to theme Converse? Then read the :doc:`theming <theming>`
|
||||
documentation.
|
||||
|
@ -1,93 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/security.rst">Edit me on GitHub</a></div>
|
||||
|
||||
=======================
|
||||
Security considerations
|
||||
=======================
|
||||
|
||||
.. note::
|
||||
Converse comes with no warranty of any kind and the authors are not liable for any damages.
|
||||
|
||||
The data-structures of Converse encapsulate sensitive user data such as
|
||||
XMPP account details (in case of manual login) and personal conversations.
|
||||
|
||||
In an environment where, besides Converse, other untrusted 3rd party scripts
|
||||
might also be running, it's important to guard against malicious or invasive
|
||||
access to user data and/or the API.
|
||||
|
||||
The threat model
|
||||
================
|
||||
|
||||
The following threat model is considered:
|
||||
|
||||
Malicious 3rd party scripts served through compromised side-channels, such as ad-networks,
|
||||
which attempt to access Converse's API and/or data-structures in order to personify users
|
||||
or to pilfer their data.
|
||||
|
||||
Mitigating measures
|
||||
===================
|
||||
|
||||
As of version 3.0.0, the following actions were taken to harden Converse against attacks:
|
||||
|
||||
Separate code/data into public and private parts
|
||||
------------------------------------------------
|
||||
|
||||
1. Encapsulate Converse's data structures into a private closured object (named ``_converse``).
|
||||
2. Split the API into public and private parts.
|
||||
|
||||
Restrict access to private code/data
|
||||
------------------------------------
|
||||
|
||||
3. Only plugins are allowed to access the private API and the closured ``_converse`` object.
|
||||
4. TODO: Whitelist plugins that have access to the private API and closured ``_converse`` object.
|
||||
5. Prevent the removal of registered plugins (otherwise the whitelist could be circumvented).
|
||||
6. Throw an error when multiple plugins try to register under the same name
|
||||
(otherwise the whitelist could be circumvented).
|
||||
|
||||
.. note::
|
||||
Care should be taken when using a custom build of Converse where some
|
||||
of the core plugins contained in the default build are omitted. In this case
|
||||
the omitted plugins should also be removed from the whitelist, otherwise
|
||||
malicious plugins could be registered under their names.
|
||||
|
||||
Addititional measures
|
||||
=====================
|
||||
|
||||
Besides the measures mentioned above, integrators and hosts can also take
|
||||
further security precautions.
|
||||
|
||||
The most effective is to avoid serving untrusted 3rd party JavaScript (e.g.
|
||||
advertisements and analytics).
|
||||
|
||||
Another option is to forego the use of a global ``converse`` object (which
|
||||
exposes the public API) and instead to encapsulate it inside a private closure,
|
||||
in order to keep it inaccessible to other scripts.
|
||||
|
||||
|
||||
Other considerations
|
||||
====================
|
||||
|
||||
Locally cached data
|
||||
-------------------
|
||||
|
||||
Besides the "hot" data stored in models and collections, which are all
|
||||
encapsulated in the private ``_converse`` object, there is also the cached data
|
||||
stored in the browser's ``sessionStorage`` and ``localStorage`` stores.
|
||||
|
||||
Examples of sensitive cached data are chat messages and the contacts roster,
|
||||
both which are in session storage, which means that the cache is cleared as
|
||||
soon as the last tab or window is closed. User credentials are not cached at
|
||||
all.
|
||||
|
||||
Perhaps the ability to encrypt this cached data could be added in future
|
||||
versions of Converse, if there is sufficient demand for it.
|
||||
|
||||
However to date no significant mitigation or hardening measures have been taken to
|
||||
secure this cached data.
|
||||
|
||||
Therefore, the best defence as website host is to avoid serving Converse with
|
||||
untrusted 3rd party code, and the best defence as an end-user is to avoid chatting
|
||||
on websites that host untrusted 3rd party code. The most common examples of such
|
||||
being advertising and analytics scripts.
|
||||
|
@ -1,205 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/session.rst">Edit me on GitHub</a></div>
|
||||
|
||||
==================
|
||||
Session Management
|
||||
==================
|
||||
|
||||
.. _`session-support`:
|
||||
|
||||
Shared Sessions
|
||||
===============
|
||||
|
||||
It's possible to enable shared sessions whereby users already
|
||||
logged in to your website will also automatically be logged in on the XMPP server,
|
||||
|
||||
Once a user is logged in, the session will be kept alive across page loads.
|
||||
|
||||
There are a few ways to let your users be automatically authenticated to an
|
||||
XMPP server once they've logged in to your site.
|
||||
|
||||
|
||||
Option 1). Server-side authentication via BOSH prebinding
|
||||
---------------------------------------------------------
|
||||
|
||||
To **prebind** refers to a technique whereby your web application sets up an
|
||||
authenticated BOSH session with the XMPP server or a standalone `BOSH <https://xmpp.org/about-xmpp/technology-overview/bosh/>`_
|
||||
connection manager.
|
||||
|
||||
Once authenticated, it receives RID and SID tokens which need to be passed
|
||||
on to Converse. Converse will then attach to that same session using
|
||||
those tokens.
|
||||
|
||||
It's called "prebind" because you bind to the BOSH session beforehand, and then
|
||||
later in the page you just attach to that session again.
|
||||
|
||||
The RID and SID tokens can be passed in manually when calling
|
||||
`converse.initialize`, but a more convenient way is to pass Converse a :ref:`prebind_url`
|
||||
which it will call when it needs the tokens. This way it will be able to
|
||||
automatically reconnect whenever the connection drops, by simply calling that
|
||||
URL again to fetch new tokens.
|
||||
|
||||
Prebinding reduces network traffic and also speeds up the startup time for
|
||||
Converse. Additionally, because prebind works with tokens, it's not necessary
|
||||
for the XMPP client to know or store users' passwords.
|
||||
|
||||
One potential drawback of using prebind is that in order to establish the
|
||||
authenticated BOSH session server-side, you'll need to access and pass on the XMPP
|
||||
credentials server-side, which, unless you're using tokens, means that you'll
|
||||
need to store XMPP passwords in cleartext.
|
||||
|
||||
This is however not the case if you for example use LDAP or Active Directory as
|
||||
your authentication backend, since you could then configure your XMPP server to
|
||||
use that as well.
|
||||
|
||||
To prebind you will require a BOSH-enabled XMPP server for Converse to connect to
|
||||
(see the :ref:`bosh-service-url` under :ref:`configuration-settings`)
|
||||
as well as a BOSH client in your web application (written for example in
|
||||
Python, Ruby or PHP) that will set up an authenticated BOSH session, which
|
||||
Converse can then attach to.
|
||||
|
||||
.. note::
|
||||
A BOSH server acts as a bridge between HTTP, the protocol of the web, and
|
||||
XMPP, the instant messaging protocol.
|
||||
|
||||
Converse can only communicate via HTTP (or websocket, in which case BOSH can't be used).
|
||||
It cannot open TCP sockets to communicate to an XMPP server directly.
|
||||
|
||||
So the BOSH server acts as a middle man, translating our HTTP requests into XMPP stanzas and vice versa.
|
||||
|
||||
Jack Moffitt has a great `blogpost <http://metajack.im/2008/10/03/getting-attached-to-strophe>`_
|
||||
about this and even provides an
|
||||
`example Django application <https://github.com/metajack/strophejs/tree/master/examples/attach>`_
|
||||
to demonstrate it.
|
||||
|
||||
When you authenticate to the XMPP server on your backend application (for
|
||||
example via a BOSH client in Django), you'll receive two tokens, RID (request ID) and SID (session ID).
|
||||
|
||||
The **Session ID (SID)** is a unique identifier for the current *session*. This
|
||||
number stays constant for the entire session.
|
||||
|
||||
The **Request ID (RID)** is a unique identifier for the current *request* (i.e.
|
||||
page load). Each page load is a new request which requires a new unique RID.
|
||||
The best way to achieve this is to simply increment the RID with each page
|
||||
load.
|
||||
|
||||
You'll need to configure Converse with the :ref:`prebind` :ref:`prebind_url` settings.
|
||||
|
||||
Please read the documentation on those settings for a fuller picture of what
|
||||
needs to be done.
|
||||
|
||||
Example code for server-side prebinding
|
||||
***************************************
|
||||
|
||||
* PHP:
|
||||
See `xmpp-prebind-php <https://github.com/candy-chat/xmpp-prebind-php>`_ by
|
||||
Michael Weibel and the folks from Candy chat.
|
||||
|
||||
* Python:
|
||||
See this `example Django application`_ by Jack Moffitt.
|
||||
|
||||
|
||||
Option 2). Delegated authentication, also called external authentication
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Delegated authentication refers to the usecase where the XMPP server delegates
|
||||
authentication to some other service.
|
||||
|
||||
This could be to LDAP or Active Directory (as shown in the diagram at the top
|
||||
of the page), or it could be to an OAuth provider, a SQL server to a specific
|
||||
website.
|
||||
|
||||
The Prosody webserver has various user-contributed modules which delegate
|
||||
authentication to external services. They are listed in the `Prosody community modules
|
||||
page <https://modules.prosody.im/>`_. Other XMPP servers have similar plugin modules.
|
||||
|
||||
If your web-application has access to the same credentials, it can send those
|
||||
credentials to Converse so that user's are automatically logged in when the
|
||||
page loads.
|
||||
|
||||
This is can be done by setting :ref:`auto_login` to true and configuring the
|
||||
the :ref:`credentials_url` setting.
|
||||
|
||||
Option 3). Temporary authentication tokens
|
||||
------------------------------------------
|
||||
|
||||
The first option has the drawback that your web-application needs to know the
|
||||
XMPP credentials of your users and that they need to be stored in the clear.
|
||||
|
||||
The second option has that same drawback and it also needs to pass those
|
||||
credentials to Converse.
|
||||
|
||||
To avoid these drawbacks, you can instead let your backend web application
|
||||
generate temporary authentication tokens which are then sent to the XMPP server
|
||||
which in turn delegates authentication to an external authentication provider
|
||||
(generally the same web-app that generated the tokens).
|
||||
|
||||
This can be combined with prebind or with the :ref:`credentials_url` setting.
|
||||
|
||||
Option 4). Cryptographically signed tokens
|
||||
------------------------------------------
|
||||
|
||||
A third potential option is to generate cryptographically signed tokens (e.g.
|
||||
HMAC tokens) which the XMPP server could authenticate by checking that they're
|
||||
signed with the right key and that they conform to some kind of pre-arranged
|
||||
format.
|
||||
|
||||
In this case, you would also use the :ref:`credentials_url` setting, to specify a
|
||||
URL from which Converse should fetch the username and token.
|
||||
|
||||
|
||||
Keeping users logged-in across page reloads
|
||||
===========================================
|
||||
|
||||
If you've properly set up :ref:`shared session support <session-support>`, then
|
||||
your users will stay logged-in to the XMPP server upon page reloads.
|
||||
|
||||
However, if users are logging in manually, then users might get logged out between requests.
|
||||
|
||||
Credential Management API
|
||||
-------------------------
|
||||
|
||||
Users with modern browsers which properly support the
|
||||
`Credential Management API <https://w3c.github.io/webappsec-credential-management>`_
|
||||
should be automatically logged-in across page reloads and therefore maintain
|
||||
their sessions.
|
||||
|
||||
Using a cookie
|
||||
--------------
|
||||
|
||||
The main reason why users can get logged-out between page reloads is because we
|
||||
don't (and can't) use cookies to maintain user sessions as is usually done with
|
||||
websites.
|
||||
|
||||
This is because XMPP servers generally don't have support for logging in with a
|
||||
cookie. It would be theoretically possible to login with SASL-EXTERNAL and a
|
||||
cookie which the XMPP server looks up as part of the BOSH HTTP request or the
|
||||
websocket connection, but no XMPP servers currently support this out of the
|
||||
box.
|
||||
|
||||
Prosody does have a plugin called `mod_auth_http_cookie <https://modules.prosody.im/mod_auth_http_cookie.html>`_
|
||||
which does the above. You'd have to `configure Converse.js to use SASL-EXTERNAL <https://opkode.com/blog/strophe_converse_sasl_external/>`_
|
||||
and then set up Prosody with that plugin. (Note, I haven't yet tested this setup personally).
|
||||
|
||||
This is however not a cross-platform solution and won't work for hosters who
|
||||
want to support all or multple XMPP servers.
|
||||
|
||||
Storing the password in localStorage
|
||||
------------------------------------
|
||||
|
||||
Since cookies are usually not an option, people have suggested storing the
|
||||
password in localStorage and logging in with it again when the user reloads the
|
||||
page.
|
||||
|
||||
We've purposefully not put this functionality in Converse.js due to the
|
||||
security implications of storing plaintext passwords in localStorage.
|
||||
|
||||
|
||||
Storing the SASL SCRAM-SHA1 hash in IndexedDB
|
||||
---------------------------------------------
|
||||
|
||||
Another suggestion that's been suggested is to store the SCRAM-SHA1 computed
|
||||
``clientKey`` in localStorage and to use that upon page reload to log the user in again.
|
||||
|
||||
This has been implemented since version 10, see documentation on `reuse_scram_keys <https://conversejs.org/docs/html/configuration.html#reuse-scram-keys>`_
|
@ -1,284 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/setup.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _what-you-will-need:
|
||||
|
||||
=====================
|
||||
Setup and integration
|
||||
=====================
|
||||
|
||||
This page documents what you'll need to do to be able to connect Converse with
|
||||
your own XMPP server and to better integrate it into your website.
|
||||
|
||||
At the very least you'll need Converse and an :ref:`XMPP server` with
|
||||
:ref:`websocket-section` or :ref:`BOSH-section` enabled. That's definitely
|
||||
enough to simply demo Converse or to do development work on it.
|
||||
|
||||
For end-to-end encryption via OMEMO, you'll need to load `libsignal-protocol.js
|
||||
<https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in
|
||||
your page. Take a look at the section on :ref:`libsignal <dependency-libsignal>` and the
|
||||
:ref:`security considerations around OMEMO <feature-omemo>`.
|
||||
|
||||
If you want to more fully integrate it into a website
|
||||
then you'll likely need to set up more services and components.
|
||||
|
||||
The diagram below shows a fairly common setup for a website or intranet:
|
||||
|
||||
* Converse runs in the web-browser on the user's device.
|
||||
|
||||
* It communicates with the XMPP server via BOSH or websocket which is usually
|
||||
reverse-proxied by a web-server in order to overcome cross-site scripting
|
||||
restrictions in the browser.
|
||||
|
||||
* Optionally the XMPP server is configured to use a SQL database for storing
|
||||
archived chat messages.
|
||||
|
||||
* Optionally there is a user directory such as Active Directory or LDAP, which
|
||||
the XMPP server is configured to use, so that users can log in with those
|
||||
credentials.
|
||||
|
||||
* Usually (but optionally) there is a backend web application which hosts a
|
||||
website in which Converse appears.
|
||||
|
||||
.. figure:: images/diagram.png
|
||||
:align: center
|
||||
:alt: A diagram of a possible setup, consisting of Converse, a web server, a backend web application, an XMPP server, a user directory such as LDAP and an XMPP server.
|
||||
|
||||
This diagram shows the various services in a fairly common setup (image generated with `draw.io <https://draw.io>`_).
|
||||
|
||||
----------------------
|
||||
The various components
|
||||
----------------------
|
||||
|
||||
.. _`XMPP server`:
|
||||
|
||||
An XMPP server
|
||||
==============
|
||||
|
||||
Converse uses `XMPP <https://xmpp.org/about-xmpp/>`_ as its
|
||||
messaging protocol, and therefore needs to connect to an XMPP/Jabber
|
||||
server (Jabber® is an older and more user-friendly synonym for XMPP).
|
||||
|
||||
You can connect to public XMPP servers like ``conversejs.org`` but if you want to
|
||||
integrate Converse into your own website and to use your website's
|
||||
authentication sessions to log in users to the XMPP server (i.e. :ref:`session support <session-support>`)
|
||||
then you'll have to set up your own XMPP server.
|
||||
|
||||
You can find a list of public XMPP servers/providers on `compliance.conversations.im <http://compliance.conversations.im/>`_
|
||||
and a list of servers that you can set up yourself on `xmpp.org <https://xmpp.org/xmpp-software/servers/>`_.
|
||||
|
||||
.. _`BOSH-section`:
|
||||
|
||||
BOSH (XMPP-over-HTTP)
|
||||
=====================
|
||||
|
||||
Web-browsers do not allow the persistent, direct TCP socket connections used by
|
||||
desktop XMPP clients to communicate with XMPP servers.
|
||||
|
||||
Instead, we have HTTP and websocket as available protocols.
|
||||
|
||||
`BOSH`_ can be seen as XMPP-over-HTTP. In other words, it allows for XMPP
|
||||
stanzas to be sent over an HTTP connection.
|
||||
|
||||
HTTP connections are stateless and usually shortlived.
|
||||
XMPP connections on the other hand are stateful and usually last much longer.
|
||||
|
||||
So to enable a web application like Converse to communicate with an XMPP
|
||||
server, we need a proxy which acts as a bridge between these two protocols.
|
||||
|
||||
This is the job of a BOSH connection manager. BOSH (Bidirectional-streams Over
|
||||
Synchronous HTTP) is a protocol for allowing XMPP communication over HTTP. The
|
||||
protocol is defined in `XEP-0206: XMPP Over BOSH <https://xmpp.org/extensions/xep-0206.html>`_.
|
||||
|
||||
Popular XMPP servers such as `Ejabberd <http://www.ejabberd.im>`_,
|
||||
Prosody `(mod_bosh) <http://prosody.im/doc/setting_up_bosh>`_ and
|
||||
`OpenFire <http://www.igniterealtime.org/projects/openfire/>`_ all include
|
||||
their own BOSH connection managers (but you usually have to enable them in the
|
||||
configuration).
|
||||
|
||||
However, if you intend to support multiple different servers (like
|
||||
https://conversejs.org does), then you'll need a standalone connection manager.
|
||||
|
||||
For a standalone manager, see for example `Punjab <https://github.com/twonds/punjab>`_
|
||||
and `node-xmpp-bosh <https://github.com/dhruvbird/node-xmpp-bosh>`_.
|
||||
|
||||
The demo on the `Converse homepage <https://conversejs.org>`_ uses a connection
|
||||
manager located at https://conversejs.org/http-bind.
|
||||
|
||||
This connection manager is available for testing purposes only, please don't
|
||||
use it in production.
|
||||
|
||||
Refer to the :ref:`bosh-service-url` configuration setting for information on
|
||||
how to configure Converse to connect to a BOSH URL.
|
||||
|
||||
Configuring your webserver for BOSH
|
||||
-----------------------------------
|
||||
|
||||
Lets say the domain under which you host Converse is *example.org:80*,
|
||||
but the domain of your connection manager or the domain of
|
||||
your HTTP file server (for `XEP-0363 HTTP File Upload <https://xmpp.org/extensions/xep-0363.html>`_)
|
||||
is at a different domain, either a different port like *example.org:5280* or a
|
||||
different name like *elsehwere.org*.
|
||||
|
||||
In such a situation the same-origin security policy of the browser comes into force.
|
||||
For security purposes a browser does not by default allow a website to
|
||||
make certain types of requests to other domains.
|
||||
|
||||
There are two ways in which you can solve this problem.
|
||||
|
||||
.. _CORS:
|
||||
|
||||
1. Cross-Origin Resource Sharing (CORS)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
CORS is a technique for overcoming browser restrictions related to the
|
||||
`same-origin security policy <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy>`_.
|
||||
|
||||
CORS is enabled by adding an ``Access-Control-Allow-Origin`` header. Where this
|
||||
is configured depends on what webserver is used for your file upload server.
|
||||
|
||||
|
||||
2. Reverse-proxy
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Another possible solution is to add a reverse proxy to a webserver such as Nginx or Apache to ensure that
|
||||
all services you use are hosted under the same domain name and port.
|
||||
|
||||
Examples:
|
||||
*********
|
||||
|
||||
Assuming your site is accessible on port ``80`` for the domain ``mysite.com``
|
||||
and your connection manager manager is running at ``someothersite.com/http-bind``.
|
||||
|
||||
The *bosh_service_url* value you want to give Converse to overcome
|
||||
the cross-domain restriction is ``mysite.com/http-bind`` and not
|
||||
``someothersite.com/http-bind``.
|
||||
|
||||
Your ``nginx`` or ``apache`` configuration will look as follows:
|
||||
|
||||
Nginx
|
||||
^^^^^
|
||||
|
||||
.. code-block:: nginx
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80
|
||||
server_name mysite.com;
|
||||
|
||||
location = / {
|
||||
root /path/to/converse.js/; # Properly set the path here
|
||||
index index.html;
|
||||
}
|
||||
location ~ ^/http-bind/ {
|
||||
proxy_pass http://someothersite.com;
|
||||
}
|
||||
# CORS
|
||||
location ~ .(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$ {
|
||||
add_header Access-Control-Allow-Origin "*"; # Decide here whether you want to allow all or only a particular domain
|
||||
root /path/to/converse.js/; # Properly set the path here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Apache
|
||||
^^^^^^
|
||||
|
||||
.. code-block:: apache
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName mysite.com
|
||||
RewriteEngine On
|
||||
RewriteRule ^/http-bind(.*) http://someothersite.com/http-bind$1 [P,L]
|
||||
</VirtualHost>
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you're getting XML parsing errors for your BOSH endpoint, for
|
||||
example::
|
||||
|
||||
XML Parsing Error: mismatched tag. Expected: </hr>.
|
||||
Location: https://example.org/http-bind/
|
||||
Line Number 6, Column 3: bosh-anon:6:3
|
||||
Also ERROR: request id 12.2 error 504 happened
|
||||
|
||||
Then your BOSH proxy is returning an HTML error page (for a 504 error in
|
||||
the above example).
|
||||
|
||||
This might be because your webserver and BOSH proxy have the same timeout
|
||||
for BOSH requests. Because the webserver receives the request slightly earlier,
|
||||
it gives up a few microseconds before the XMPP server’s empty result and thus returns a
|
||||
504 error page containing HTML to browser, which then gets parsed as if its
|
||||
XML.
|
||||
|
||||
To fix this, make sure that the webserver's timeout is slightly higher.
|
||||
In Nginx you can do this by adding ``proxy_read_timeout 61;``;
|
||||
|
||||
From Converse 4.0.0 onwards the default ``wait`` time is set to 59 seconds, to avoid
|
||||
this problem.
|
||||
|
||||
|
||||
|
||||
.. _`websocket-section`:
|
||||
|
||||
Websocket
|
||||
=========
|
||||
|
||||
Websockets provide an alternative means of connection to an XMPP server from
|
||||
your browser.
|
||||
|
||||
Websockets provide long-lived, bidirectional connections which do not rely on
|
||||
HTTP. Therefore BOSH, which operates over HTTP, doesn't apply to websockets.
|
||||
|
||||
`Prosody <http://prosody.im>`_ (from version 0.10) and `Ejabberd <http://www.ejabberd.im>`_ support websocket connections, as
|
||||
does the node-xmpp-bosh connection manager.
|
||||
|
||||
Refer to the :ref:`websocket-url` configuration setting for information on how to
|
||||
configure Converse to connect to a websocket URL.
|
||||
|
||||
|
||||
Reverse-proxy for a websocket connection
|
||||
----------------------------------------
|
||||
|
||||
Assuming your website is accessible on port ``443`` on the domain ``mysite.com``
|
||||
and your XMPP server's websocket server is running at ``localhost:5280/xmpp-websocket``.
|
||||
|
||||
You can then set up your webserver as an SSL enabled reverse proxy in front of
|
||||
your websocket endpoint.
|
||||
|
||||
The :ref:`websocket-url` value you'll want to pass in to ``converse.initialize`` is ``wss://mysite.com/xmpp-websocket``.
|
||||
|
||||
Your ``nginx`` will look as follows:
|
||||
|
||||
.. code-block:: nginx
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 443
|
||||
server_name mysite.com;
|
||||
ssl on;
|
||||
ssl_certificate /path/to/fullchain.pem; # Properly set the path here
|
||||
ssl_certificate_key /path/to/privkey.pem; # Properly set the path here
|
||||
|
||||
location = / {
|
||||
root /path/to/converse.js/; # Properly set the path here
|
||||
index index.html;
|
||||
}
|
||||
location /xmpp-websocket {
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://127.0.0.1:5280;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
}
|
||||
# CORS
|
||||
location ~ .(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$ {
|
||||
add_header Access-Control-Allow-Origin "*"; # Decide here whether you want to allow all or only a particular domain
|
||||
root /path/to/converse.js/; # Properly set the path here
|
||||
}
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/setup_dev_environment.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`setup_dev_environment`:
|
||||
|
||||
============================
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Installing the 3rd party dependencies
|
||||
=====================================
|
||||
|
||||
To develop and customize Converse, you'll first need to check out Converse's Git
|
||||
repository:
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/conversejs/converse.js.git
|
||||
cd converse.js
|
||||
|
||||
|
||||
We use development tools which depend on Node.js and NPM (the Node package manager).
|
||||
|
||||
It's recommended that you use `NVM <https://github.com/nvm-sh/nvm>`_ (the Node version manager)
|
||||
to make sure you have the right version of Node.
|
||||
|
||||
Refer to the `NVM Github page <https://github.com/nvm-sh/nvm#install--update-script>`_ for instructions on how to install it.
|
||||
|
||||
Once NVM is installed, you can run the following inside your checkout of the Converse Git repository:
|
||||
|
||||
::
|
||||
|
||||
nvm install
|
||||
|
||||
.. note::
|
||||
You will always have to first run ``nvm install`` in a new terminal session in order to use the
|
||||
recommended version of Node before working on Converse.
|
||||
|
||||
|
||||
To set up the Converse development environment, you now run ``make dev``.
|
||||
|
||||
::
|
||||
|
||||
make dev
|
||||
|
||||
Alternatively, if you're using Windows, or don't have GNU Make installed, you can run the
|
||||
following:
|
||||
|
||||
::
|
||||
|
||||
npm install
|
||||
npm run lerna
|
||||
|
||||
This will install the Node development tools and Converse's dependencies.
|
||||
|
||||
The front-end dependencies are those JavaScript files on which
|
||||
Converse directly depends and which will be loaded in the browser as part of
|
||||
the bundle in ``dist/converse.js`` (or ``dist/converse.min.js``).
|
||||
|
||||
To see the 3rd party dependencies (not just the front-end dependencies, but
|
||||
also ones necessary for development tasks like making builds), take a look at
|
||||
the list under the ``devDependencies`` in `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
|
||||
|
||||
.. note::
|
||||
After running ```make dev```, you should now have a new *node_modules* directory
|
||||
which contains all the external dependencies of Converse.
|
||||
If this directory does NOT exist, something must have gone wrong.
|
||||
Double-check the output of ```make dev``` to see if there are any errors
|
||||
listed. For support, you can ask in our chatroom: `dicuss@conference.conversejs.org <xmpp:discuss@conference.conversejs.org>`_.
|
||||
|
||||
If you don't have an XMPP client installed, follow this link to
|
||||
`conversejs.org <https://conversejs.org/fullscreen#converse/room?jid=discuss@conference.conversejs.org>`_
|
||||
where you can log in and be taken directly to the chatroom.
|
||||
|
||||
|
||||
.. _`dependency-libsignal`:
|
||||
|
||||
Libsignal
|
||||
---------
|
||||
|
||||
If you want OMEMO encryption, you need to load `libsignal <https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in your page.
|
||||
|
||||
For example::
|
||||
|
||||
<script src="3rdparty/libsignal-protocol-javascript/dist/libsignal-protocol.js"></script>
|
||||
|
||||
The reason libsignal needs to be loaded separately is because it's released
|
||||
under the `GPLv3 <https://github.com/signalapp/libsignal-protocol-javascript/blob/master/LICENSE>`_
|
||||
which requires all other dependent JavaScript code to also be open sourced under the same
|
||||
license. You might not be willing to adhere to those terms, which is why you
|
||||
need to decide for yourself whether you're going to load libsignal or not.
|
||||
|
||||
|
||||
.. _`webserver`:
|
||||
|
||||
Setting up a webserver
|
||||
======================
|
||||
|
||||
When making changes to Converse, either development or theming changes,
|
||||
you'll want to preview them in your browser.
|
||||
|
||||
For this, you'll need to serve the development files via a web server,
|
||||
so that you can see your local changes in the browser.
|
||||
|
||||
Manually starting a web server
|
||||
------------------------------
|
||||
|
||||
To both set up the development environment and also start up a web browser to
|
||||
serve the files for you, you can run::
|
||||
|
||||
make serve
|
||||
|
||||
.. note::
|
||||
To run the "make" commands, you'll need `GNUMake <https://www.gnu.org/software/make>`_
|
||||
installed on your computer. If you use GNU/Linux or \*BSD, it should be installed or
|
||||
available via your package manager. For Mac, you'll need to install XCode and in
|
||||
Windows you can use `Chocolatey <https://chocolatey.org/>`_.
|
||||
|
||||
After running ``make serve`` you can open http://localhost:8000 in your webbrowser to see the Converse website.
|
||||
|
||||
When developing or changing the theme, you'll want to load all the
|
||||
unminified JS and CSS resources as separate files. To do this, open http://localhost:8000/dev.html instead.
|
||||
|
||||
You might want to open `dev.html <https://github.com/conversejs/converse.js/blob/master/dev.html>`_ in your text editor or IDE as well, to see
|
||||
how ``converse.initialize`` is called and to potentially change any of the
|
||||
settings.
|
||||
|
||||
Starting a web server with live reloading
|
||||
-----------------------------------------
|
||||
|
||||
Alternatively, if you want to have live reloading whenever any of the source files change, you
|
||||
can run ``make devserver`` (which will use `webpack-dev-server <https://github.com/webpack/webpack-dev-server>`_).
|
||||
|
||||
Instead of ``dev.html`` being used, `webpack.html <https://github.com/conversejs/converse.js/blob/master/webpack.html>`_
|
||||
is now being used as the HTML template, and you'll need to modify that file if
|
||||
you want to change the settings passed to ``converse.initialize``.
|
||||
|
||||
If you're running ``make devserver``, you need to open http://localhost:8080.
|
||||
|
@ -1,165 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/style_guide.rst">Edit me on GitHub</a></div>
|
||||
|
||||
Software Style Guide
|
||||
====================
|
||||
|
||||
Most of the style guide recommendations here come from Douglas Crockford's book
|
||||
`JavaScript, the good parts <http://shop.oreilly.com/product/9780596517748.do>`_
|
||||
|
||||
Tabs or spaces?
|
||||
---------------
|
||||
|
||||
We always indent 4 spaces.
|
||||
|
||||
Underscores or camelCase?
|
||||
-------------------------
|
||||
|
||||
We use camelCase for function names and underscores for variables names.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
function thisIsAFunction () {
|
||||
let this_is_a_variable;
|
||||
...
|
||||
}
|
||||
|
||||
const versus let
|
||||
----------------
|
||||
|
||||
Try to use `const` whenever possible. If a variable won't be reassigned, use
|
||||
`const`, otherwise use `let`.
|
||||
|
||||
Spaces around operators
|
||||
-----------------------
|
||||
|
||||
In general, spaces are put around operators, such as the equals ``=`` or plus ``+`` signs.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
if (sublocale != locale) {
|
||||
// do something
|
||||
}
|
||||
|
||||
An exception is when they appear inside for-loop expressions, for example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
for (i=0; i<msgs_length; i++) {
|
||||
// do something
|
||||
}
|
||||
|
||||
Generally though, rather err on the side of adding spaces, since they make the
|
||||
code much more readable.
|
||||
|
||||
destructuring
|
||||
-------------
|
||||
|
||||
When assigning to a variable via destructuring, add spaces between the curly
|
||||
brackets.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const { foo } = bar;
|
||||
|
||||
|
||||
Global constants are written in ALL_CAPS
|
||||
----------------------------------------
|
||||
|
||||
Global identifiers that denote constant values should be written in
|
||||
all capital letters, with underscores between words.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const SECONDS_IN_HOUR = 3600;
|
||||
|
||||
function update () {
|
||||
const timeout = 20;
|
||||
let seconds_since_message = 0;
|
||||
// other stuff here
|
||||
}
|
||||
|
||||
|
||||
Function declaration and invocation
|
||||
-----------------------------------
|
||||
|
||||
When declaring a function, the function name and the brackets after it are separated
|
||||
with a space. Like so:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
function update (model) {
|
||||
model.foo = 'bar';
|
||||
}
|
||||
|
||||
When calling the same function, the brackets are written without a space in
|
||||
between:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
update(model);
|
||||
|
||||
This is to make a more explicit visual distinction between method declarations
|
||||
and method invocations.
|
||||
|
||||
Checking for equality
|
||||
---------------------
|
||||
|
||||
JavaScript has a strict ``===`` and less strict ``==`` equality operator. The
|
||||
stricter equality operator also does type checking. To avoid subtle bugs when
|
||||
doing comparisons, always use the strict equality check.
|
||||
|
||||
Curly brackets
|
||||
--------------
|
||||
|
||||
Curly brackets must appear on the same lines as the ``if`` and ``else`` keywords.
|
||||
The closing curly bracket appears on its own line.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
if (locales[locale]) {
|
||||
return locales[locale];
|
||||
} else {
|
||||
sublocale = locale.split("-")[0];
|
||||
if (sublocale != locale && locales[sublocale]) {
|
||||
return locales[sublocale];
|
||||
}
|
||||
}
|
||||
|
||||
Always enclose blocks in curly brackets
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When writing a block such as an ``if`` or ``while`` statement, always use
|
||||
curly brackets around that block of code. Even when not strictly required by
|
||||
the compiler (for example if its only one line inside the ``if`` statement).
|
||||
|
||||
For example, like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
if (condition === true) {
|
||||
this.updateRoomsList();
|
||||
}
|
||||
somethingElse();
|
||||
|
||||
and NOT like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
if (converse.auto_list_rooms)
|
||||
this.updateRoomsList();
|
||||
somethingElse();
|
||||
|
||||
This is to aid in readability and to avoid subtle bugs where certain lines are
|
||||
wrongly assumed to be executed within a block.
|
@ -1,64 +0,0 @@
|
||||
Automated tests
|
||||
===============
|
||||
|
||||
Converse uses the `Karma <https://karma-runner.github.io/latest/index.html>`_ test runner and
|
||||
`Jasmine <https://jasmine.github.io/>`_ testing library for running tests.
|
||||
|
||||
In addition, we use `ESlint <https://eslint.org/>`_ to run a static analysis (aka
|
||||
linting) of the source files and report errors.
|
||||
|
||||
Whenever a commit is pushed to the Converse Github repo, all ESlint checks and
|
||||
Jasmine tests are run on `Travis CI <https://travis-ci.org/github/conversejs/converse.js>`_.
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
|
||||
You can run ESlint by typing ``make eslint``. Similarly the tests can be run via ``make tests``.
|
||||
|
||||
To run both eslint and the tests, you can use ``make check``.
|
||||
|
||||
When running ``make test`` or ``make check``, a browser will automatically
|
||||
start up, open a tab at http://localhost:9876 and start running the tests.
|
||||
|
||||
You'll see a green bar at the top of the page, and on the right inside it is a ``Debug`` button.
|
||||
|
||||
It's often helpful to click that button and run the tests in debug mode. This
|
||||
way, you see better error output for failed tests.
|
||||
|
||||
Automatically run tests on file changes
|
||||
***************************************
|
||||
|
||||
To automatically run the tests whenever you make a change to any of the
|
||||
Converse source code, you can run ``make watch`` in one terminal, and ``make tests`` in another.
|
||||
|
||||
``make watch`` will build development bundles of Converse (in ``dist/converse.js`` and ``dist/converse.css``)
|
||||
and automatically rebuild them whenever a source file is modified.
|
||||
|
||||
Similarly, Karma will make sure that the tests are re-executed when the bundle files are rebuilt.
|
||||
|
||||
Running individual tests
|
||||
************************
|
||||
|
||||
Converse has over 400 tests, and it can take a while to run through all of them.
|
||||
|
||||
When developing on Converse, it's often preferable to have a more rapid
|
||||
turnaround time between editing a file and checking whether the most relevant
|
||||
tests have passed.
|
||||
|
||||
Jasmine tests are described by `it` functions and the tests names are written to
|
||||
be read as plain English sentences that start with the word ``it``.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
it("is rejected if it's an unencapsulated forwarded message",
|
||||
|
||||
Tests are grouped by `describe` functions, and contained in spec files inside
|
||||
the `spec <https://github.com/jcbrand/converse.js/blob/master/spec/>`_ directory.
|
||||
|
||||
To run only a single test, you can replace ``it(`` with ``fit(`` for the particular
|
||||
test that you want to run. You can also do this for multiple tests. All of them
|
||||
will be run whenever ``make test`` executes.
|
||||
|
||||
To run only a group of tests, you can similarly replace ``describe(`` with ``fdescribe``.
|
@ -1,145 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _theming:
|
||||
|
||||
=======
|
||||
Theming
|
||||
=======
|
||||
|
||||
Setting up your environment
|
||||
===========================
|
||||
|
||||
In order to theme Converse, you first need to follow the steps for :ref:`setup_dev_environment`, including :ref:`webserver`.
|
||||
|
||||
Creating a custom theme
|
||||
=======================
|
||||
|
||||
Converse can be themed via CSS custom properties (aka CSS variables) and it has
|
||||
some themes available in its source repository.
|
||||
|
||||
A theme is a CSS file with a specific rule that defines the theme's CSS properties.
|
||||
The rule has a specific selector that must include (and determines) the theme name.
|
||||
|
||||
Inside this CSS rule, various CSS variables are assigned values.
|
||||
The CSS variables mainly refer to the colors that comprise the theme.
|
||||
If you don't specify a value for a specific CSS variable, then the value from
|
||||
the ``classic`` theme is used, as defined in `classic.scss <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes/classic.scss>`_.
|
||||
|
||||
The native theme files can be found in `shared/styles/themes <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes>`_.
|
||||
|
||||
Note, the Converse theme files have a ``.scss`` extension because they are compiled
|
||||
by the Sass compiler into normal CSS files. It's however not necessary to use
|
||||
Sass, basic CSS files will also suffice.
|
||||
|
||||
The theme that Converse uses can be set via the :ref:`theme` configuration
|
||||
setting (and the :ref:`dark_theme` configuration setting for dark mode).
|
||||
|
||||
How are themes applied?
|
||||
-----------------------
|
||||
|
||||
When you set a value for the :ref:`theme` configuration setting, Converse will add
|
||||
a class ``theme-${api.settings.get('theme')}`` on the ``converse-root`` DOM
|
||||
element.
|
||||
|
||||
So, for example, if you set the ``theme`` setting to ``"dracula"``, then the
|
||||
``converse-root`` element will get the class ``theme-dracula``.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.initialize({ theme: "dracula" });
|
||||
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<converse-root class="conversejs theme-dracula"></converse-root>
|
||||
|
||||
|
||||
The apply a theme, there then needs to be a CSS rule with a selector that matches the
|
||||
``theme-dracula`` class on the ``converse-root`` element.
|
||||
|
||||
If you take a look at the theme file `dracula.scss <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes/dracula.scss>`_
|
||||
you'll see that it defines a CSS rule with the selector
|
||||
``.conversejs.theme-dracula``.
|
||||
|
||||
This selector matches any DOM element with both the classes ``.conversejs`` and
|
||||
``.theme-dracula``. The ``converse-root`` element will already have the class
|
||||
``.conversejs`` and it will have the class ``.theme-dracula`` if the ``theme``
|
||||
(or ``dark_theme`` in dark mode) configuration setting is set to ``"dracula"``.
|
||||
|
||||
This is how themes are applied, by defining a CSS selector that matches the
|
||||
class ``.theme-${name}`` (where ``name`` is a variable containing the name of
|
||||
the theme), and then setting the ``theme`` (and/or ``dark_theme``) configuration
|
||||
setting.
|
||||
|
||||
To create your own theme, you can create a similar CSS rule that matches
|
||||
your theme's name and then you set the ``theme`` configuration setting to that
|
||||
name. This CSS rule can be in any CSS file that is loaded in your website, or
|
||||
you can even put it in the DOM as an inline style.
|
||||
|
||||
Modifying the CSS
|
||||
=================
|
||||
|
||||
To create a new theme with different colors, it should be enough to create a
|
||||
theme file that sets the various CSS variables (as described above).
|
||||
|
||||
For other CSS-related changes, you can make a specific
|
||||
CSS rule with that matches the element you want to change.
|
||||
|
||||
Sometimes it might however be neccessary to modify the core CSS files from
|
||||
Converse, for example if you're developing new features or fixing styling bugs.
|
||||
|
||||
The CSS files are generated from `Sass <http://sass-lang.com>`_ files that end in ``.scss`` and
|
||||
which are distributed throughout the source code.
|
||||
|
||||
The CSS that is relevant to a particular plugin
|
||||
is usually inside the ``./styles`` directory inside the relevant plugin directory.
|
||||
|
||||
For example: `src/plugins/controlbox/styles <https://github.com/conversejs/converse.js/tree/master/src/plugins/controlbox/styles>`_.
|
||||
|
||||
If you're running ``make watch``, then the CSS will automatically be
|
||||
regenerated when you've changed any of the ``.scss``.
|
||||
|
||||
You can also manually generate the CSS::
|
||||
|
||||
make css
|
||||
|
||||
Modifying the HTML templates of Converse
|
||||
========================================
|
||||
|
||||
Converse uses `lit-html <https://lit.dev/docs/libraries/standalone-templates/>`_ as HTML
|
||||
templating library, and the HTML source code is contained in JavaScript ``.js``
|
||||
files in various ``./template`` directories in the source code.
|
||||
|
||||
Some top-level templates are also in the ``./src/templates`` directory, but
|
||||
the templates that are relevant to a specific plugin should be inside that plugin's subdirectory.
|
||||
|
||||
For example: `src/plugins/chatview/templates <https://github.com/conversejs/converse.js/tree/master/src/plugins/chatview/templates>`_.
|
||||
|
||||
You can modify HTML markup that Converse generates by modifying these files.
|
||||
|
||||
Use webpack aliases to modify templates without changing the original files
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Generally what I do when creating a modified version of Converse for a project
|
||||
or customer, is that I create a new JavaScript package with its own
|
||||
``package.json`` and I then add ``converse.js`` as a dependency (e.g. via ``npm
|
||||
install --save converse.js``) to the ``package.json``.
|
||||
|
||||
Then I add a Webpack configuration and use `webpack aliases <https://webpack.js.org/configuration/resolve/#resolvealias>`_
|
||||
to resolve template paths to my own modified files.
|
||||
|
||||
For example, in the webpack configuration snippet below, I add two aliases, so
|
||||
that the ``message-body.js`` and ``message.js`` templates can be replaced with
|
||||
two of my own custom templates.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
alias: {
|
||||
'./message-body.js': path.resolve(__dirname, 'path/to/my/custom/message-body.js'),
|
||||
'./templates/message.js': path.resolve(__dirname, 'path/to/my/custom/chat_message.js'),
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/translations.rst">Edit me on GitHub</a></div>
|
||||
|
||||
============
|
||||
Translations
|
||||
============
|
||||
|
||||
Converse supports localization of its user interface and date formats. As
|
||||
of writing, 17 languages are supported.
|
||||
|
||||
The translations of Converse can be found in the `locale
|
||||
<https://github.com/jcbrand/converse.js/tree/master/locale>`_ directory.
|
||||
|
||||
Translations of Converse are very welcome. You can add translations either
|
||||
manually by editing the ``.po`` files in the above-mentioned ``locale``
|
||||
directory, or through the web at `weblate <https://hosted.weblate.org/projects/conversejs/#languages>`_.
|
||||
|
||||
As of version 3.3.0, Converse no longer automatically bundles translations
|
||||
in its source file and instead fetches only the relevant locale for the current
|
||||
session from a URL as specified by the :ref:`assets_path` setting.
|
||||
|
||||
There are three configuration settings relevant to translations and
|
||||
localisation. You're encouraged to read the documentation for each of them.
|
||||
|
||||
* :ref:`i18n`
|
||||
* :ref:`locales`
|
||||
* :ref:`assets_path`
|
||||
|
||||
Manually updating translations
|
||||
==============================
|
||||
|
||||
If you simply want to add a few missing translations, then consider doing it
|
||||
through the web at `weblate <https://hosted.weblate.org/projects/conversejs/#languages>`_.
|
||||
|
||||
Some things however cannot be done via weblate and instead have to be done
|
||||
manually in a checkout of the Converse source repository.
|
||||
|
||||
These tasks are documented below.
|
||||
|
||||
Updating the translations template (.pot file)
|
||||
----------------------------------------------
|
||||
|
||||
The gettext `.pot` file located in
|
||||
`./locale/converse.pot <https://github.com/jcbrand/converse.js/blob/master/locale/converse.pot>`_
|
||||
is the template containing all translations and from which for each language an individual PO
|
||||
file is generated.
|
||||
|
||||
The `.pot` file contains all translateable strings extracted from Converse.
|
||||
|
||||
To make a user-facing string translateable, wrap it in the double underscore helper
|
||||
function like so:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
__('This string will be translated at runtime');
|
||||
|
||||
After adding the string, you'll need to regenerate the POT file:
|
||||
|
||||
::
|
||||
|
||||
make pot
|
||||
|
||||
Making translations file for a new language
|
||||
-------------------------------------------
|
||||
|
||||
To create a new translations file for a language in which Converse is not yet
|
||||
translated into, do the following
|
||||
|
||||
.. note:: In this example we use Polish (pl), you need to substitute 'pl' to your own language's code.
|
||||
|
||||
::
|
||||
|
||||
mkdir -p ./locale/pl/LC_MESSAGES
|
||||
msginit -i ./locale/converse.pot -o ./locale/pl/LC_MESSAGES/converse.po -l pl
|
||||
|
||||
Please make sure to add the following attributes at the top of the file (under
|
||||
*Content-Transfer-Encoding*). They are required as configuration settings for Jed,
|
||||
the JavaScript translations library that we're using.
|
||||
|
||||
.. code-block:: po
|
||||
|
||||
"domain: converse\n"
|
||||
"lang: pl\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"plural_forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
Updating an existing translations file
|
||||
--------------------------------------
|
||||
|
||||
You can update the `.po` file for a specific language by doing the following:
|
||||
|
||||
.. note:: In this example we use German (de), you need to substitute 'de' to your own language's code.
|
||||
|
||||
::
|
||||
|
||||
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
|
||||
|
||||
To do this for ALL languages, run:
|
||||
|
||||
::
|
||||
|
||||
make po
|
||||
|
||||
The resulting `.po` file is then what gets translated.
|
||||
|
||||
Generating a JSON file from a translations file
|
||||
-----------------------------------------------
|
||||
|
||||
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_, which we use for
|
||||
translations in Converse cannot use the `.po` files directly. We have
|
||||
to generate from it a file in JSON format and then put that in a `.js` file
|
||||
for the specific language.
|
||||
|
||||
To generate JSON from a PO file, you'll need po2json for node.js. Run the
|
||||
following command to install it (npm being the node.js package manager):
|
||||
|
||||
::
|
||||
|
||||
npm install po2json
|
||||
|
||||
You can then convert the translations into JSON format:
|
||||
|
||||
::
|
||||
|
||||
po2json -p -f jed -d converse locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
|
||||
|
||||
To do this for ALL languages, run:
|
||||
|
||||
::
|
||||
|
||||
make po2json
|
||||
|
||||
|
||||
.. note::
|
||||
If you are adding translations for a new language that is not already supported,
|
||||
you'll have to add the language path in main.js and make one more edit in ./src/locales.js
|
||||
to make sure the language is loaded by require.js.
|
||||
|
||||
|
||||
Making sure the JSON file will get loaded
|
||||
------------------------------------------
|
||||
|
||||
Finally, make sure that the language code is added to the list of default
|
||||
values for the ``locales`` config setting.
|
||||
|
||||
This is done in ``src/converse-core.js``.
|
||||
|
||||
Look for the following section:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
// Default configuration values
|
||||
// ----------------------------
|
||||
this.default_settings = {
|
||||
// ... Omitted for brevity
|
||||
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
|
||||
locales: [
|
||||
'af', 'ar', 'bg', 'ca', 'de', 'es', 'en', 'fr', 'he',
|
||||
'hu', 'id', 'it', 'ja', 'nb', 'nl',
|
||||
'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'
|
||||
],
|
||||
// ... Omitted for brevity
|
||||
};
|
@ -1,224 +0,0 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/troubleshooting.rst">Edit me on GitHub</a></div>
|
||||
|
||||
=============================
|
||||
Troubleshooting and debugging
|
||||
=============================
|
||||
|
||||
General tips on debugging Converse
|
||||
==================================
|
||||
|
||||
Enabling debug output
|
||||
---------------------
|
||||
|
||||
Converse has a :ref:`loglevel` configuration setting which lets you to turn on
|
||||
debug logging in the browser's developer console.
|
||||
|
||||
When debugging, you always want to make sure that this setting is set to
|
||||
``true`` when calling ``converse.initialize``.
|
||||
|
||||
You can also enable debug output via the URL, which is useful when you don't
|
||||
have access to the server where Converse is hosted.
|
||||
|
||||
To do so, add ``#converse?loglevel=debug`` to the URL in the browser's address bar.
|
||||
Make sure to first remove any already existing URL fragment (the URL fragment
|
||||
is the part that starts with a ``#``).
|
||||
|
||||
With debug logging on, you can open the browser's developer console and study the
|
||||
data that is logged to it.
|
||||
|
||||
In Chrome you can right click in the developer console and save its contents to
|
||||
a file for later study.
|
||||
|
||||
What is logged at the debug loglevel?
|
||||
-------------------------------------
|
||||
|
||||
`Strope.js <http://strophe.im/>`_, the underlying XMPP library which Converse
|
||||
uses, swallows errors so that messaging can continue in cases where
|
||||
non-critical errors occur.
|
||||
|
||||
This is a useful feature and provides more stability, but it makes debugging
|
||||
trickier, because the app doesn't crash when something goes wrong somewhere.
|
||||
|
||||
That's why checking the debug output in the browser console is important.
|
||||
If something goes wrong somewhere, the error will be logged there and you'll be
|
||||
able to see it.
|
||||
|
||||
Additionally, Converse will in debug mode also log all XMPP stanzas
|
||||
(the XML snippets being sent between it and the server) to the console.
|
||||
This is very useful for debugging issues relating to the XMPP protocol.
|
||||
|
||||
For example, if a message or presence update doesn't appear, one of the first
|
||||
things you can do is to set ``loglevel: debug`` and then to check in the console
|
||||
whether the relevant XMPP stanzas are actually logged (which would mean that
|
||||
they were received by Converse). If they're not logged, then the problem is
|
||||
more likely on the XMPP server's end (perhaps a misconfiguration?). If they
|
||||
**are** logged, then there might be a bug or misconfiguration in Converse.
|
||||
|
||||
Performance issues with large rosters
|
||||
=====================================
|
||||
|
||||
Effort has been made to benchmark and optimize Converse to work with large
|
||||
rosters.
|
||||
|
||||
See for example the benchmarking tests in `spec/profiling.js
|
||||
<https://github.com/jcbrand/converse.js/blob/master/spec/profiling.js>`_ which
|
||||
can be used together with the `profiling features of
|
||||
Chrome <https://developer.chrome.com/devtools/docs/cpu-profiling>`_ to find
|
||||
bottlenecks in the code.
|
||||
|
||||
However, with large rosters (more than 1000 contacts), rendering in
|
||||
Converse slows down a lot and it may become intolerably slow.
|
||||
|
||||
One simple trick to improve performance is to set ``show_only_online_users: true``.
|
||||
This will (usually) reduce the amount of contacts that get rendered in the
|
||||
roster, which eases one of the remaining performance bottlenecks.
|
||||
|
||||
File upload is not working
|
||||
==========================
|
||||
|
||||
One of the most common causes for file upload not working is a lack of CORS
|
||||
support by the file server to which the file should be uploaded.
|
||||
|
||||
CORS stands for `Cross-Origin Resource Sharing (CORS) <https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS>`_
|
||||
and is a technique for overcoming browser restrictions related to the
|
||||
`same-origin security policy <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy>`_.
|
||||
|
||||
For example, if the domain under which you host Converse is *example.org*,
|
||||
but the domain of your of your HTTP file server (for `XEP-0363 HTTP File Upload <https://xmpp.org/extensions/xep-0363.html>`_)
|
||||
is *upload.example.org*, then the HTTP file server needs to enable CORS.
|
||||
|
||||
If you're not sure what the domain of the HTTP file server is, take a look at
|
||||
the console of your browser's developer tools.
|
||||
|
||||
You might see an error like this one::
|
||||
|
||||
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.de:5443/...
|
||||
|
||||
You might also see a 404 HTTP response for an OPTIONS request in the `Network Tab` of your browser's developer tools.
|
||||
|
||||
An OPTIONS request is usually a so-called
|
||||
`CORS pre-flight request <https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS#Preflighted_requests_in_CORS>`_
|
||||
which is used by the browser to find out whether the endpoint supports
|
||||
`Cross-Origin Resource Sharing (CORS) <https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS>`_.
|
||||
|
||||
If you get a 404 response for such a request, then the endpoint does NOT
|
||||
support CORS and the browser will prevent requests from being made to it.
|
||||
|
||||
This will prevent you from uploading files to it.
|
||||
|
||||
How you solve a CORS-related issue depends on your particular setup, specifically it depends on
|
||||
what you're using as the HTTP file server.
|
||||
|
||||
CORS is enabled by adding an ``Access-Control-Allow-Origin`` header, so you'll
|
||||
have to configure your file server to add this header.
|
||||
|
||||
Users don't stay logged in across page reloads
|
||||
==============================================
|
||||
|
||||
A common complaint in the Converse chat room (`<xmpp:discuss@conference.conversejs.org?join>`_)
|
||||
is that users are logged out when they reload the page.
|
||||
|
||||
The main way in which websites and web apps maintain a user's login session is via
|
||||
authentication cookies, which are included in every HTTP request sent to the server.
|
||||
|
||||
XMPP is however not HTTP, cookies aren't automatically included in traffic to
|
||||
the XMPP server and XMPP servers don't rely on cookies for authentication.
|
||||
|
||||
Instead, an XMPP client is expected to store the user credentials (username and
|
||||
password, either plaintext or hashed and salted if
|
||||
`SCRAM <https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism>`_
|
||||
is being used) and to then present those credentials to the XMPP server when authenticating.
|
||||
|
||||
This works well for non-web XMPP clients, but Converse has so far avoided
|
||||
storing user credentials in browser storage, since they can then be accessed by
|
||||
any scripts running in the browser under the same domain.
|
||||
|
||||
So what does Converse do to keep users logged in?
|
||||
-------------------------------------------------
|
||||
|
||||
Use the Web Auth API
|
||||
********************
|
||||
|
||||
Converse supports the `Web Authentication API <https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API>`_
|
||||
which let's it use the secure credential management of the browser to get the
|
||||
uesr credentials to automatically log the user in. This however requires that
|
||||
the user saves his or her username and password in the browser. Often the user
|
||||
is automatically asked by the browser whether he/she wants to store the
|
||||
credentials. If that doesn't happen, the user has to do so manually, usually by
|
||||
clicking the key icon in the address bar. This works well on most modern browsers,
|
||||
but not on Firefox, which has insufficient support for the Web Authentication API.
|
||||
|
||||
What can users do to stay logged in?
|
||||
------------------------------------
|
||||
|
||||
Outsource credential management to something else
|
||||
*************************************************
|
||||
|
||||
The issues mentioned above mostly related to users logging in manually, and not
|
||||
to integrations where Converse automatically fetches user credentials from the
|
||||
backend via the :ref:`credentials_url` setting.
|
||||
|
||||
Use BOSH instead of websocket
|
||||
*****************************
|
||||
|
||||
`BOSH <https://xmpp.org/extensions/xep-0206.html>`_ can be thought of
|
||||
XMPP-over-HTTP and because HTTP is stateless, BOSH needs to maintain login
|
||||
sessions for a certain amount of time (usually 60 seconds) even if there is no
|
||||
HTTP traffic between the client and server. This means that if you have a BOSH
|
||||
session running, you can reload the page and you will stay logged in.
|
||||
|
||||
Note, Websocket connections are however faster and have less overhead than BOSH.
|
||||
|
||||
User a browser with adequate support for the Web Auth API
|
||||
*********************************************************
|
||||
|
||||
Another option is to only use a browser with proper support for the Web Auth
|
||||
API (which mainly means avoiding Firefox) and then to save your credentials in the browser.
|
||||
|
||||
Use Converse Desktop
|
||||
********************
|
||||
|
||||
The `desktop version of Converse <https://github.com/conversejs/converse-desktop>`_
|
||||
also doesn't have this problem, since the credentials are stored in Electron
|
||||
and there is no significant risk of other malicious scripts running.
|
||||
|
||||
What else can Converse do to keep users logged in?
|
||||
--------------------------------------------------
|
||||
|
||||
This problem could also potentially be fixed by storing the
|
||||
XMPP credentials securely with web crypto and IndexedDB. This could be done by
|
||||
generating a private encryption key in non-exportable format, and then using that
|
||||
to encrypt the credentials before storing them in IndexedDB.
|
||||
|
||||
This would protect the credentials from someone who has access to your
|
||||
computer (or harddrive), but it still won't protect them from malicious scripts
|
||||
running in the same domain as Converse is being hosted, since they would have the
|
||||
same level of access as Converse itself (which legitimately needs access to the
|
||||
credentials).
|
||||
|
||||
Common errors
|
||||
=============
|
||||
|
||||
Error: A "url" property or function must be specified
|
||||
-----------------------------------------------------
|
||||
|
||||
That's a relatively generic `Skeletor <https://github.com/conversejs/skeletor>`_ (or `Backbone <http://backbonejs.org/>_`)
|
||||
error and by itself it usually doesn't give enough information to know how to fix the underlying issue.
|
||||
|
||||
Generally, this error happens when a Model is being persisted (e.g. when model.save() is called,
|
||||
but there is no information specifying where/how it should be persisted.
|
||||
|
||||
The Converse models are persisted to browser storage (e.g. sessionStorage, localStorage or IndexedDB),
|
||||
and this happens by adding a browserStorage attribute on the model, or on the collection containing the model.
|
||||
|
||||
See for example here: https://github.com/conversejs/converse.js/blob/395aa8cb959bbb7e26472ed3356160c8044be081/src/headless/converse-chat.js#L359
|
||||
|
||||
If this error occurs, it means that a model being persisted doesn't have the ``browserStorage`` attribute,
|
||||
and it's containing collection (if there is one) also doesn't have that attribute.
|
||||
|
||||
This usually happens when a model has been removed from a collection, and then ``.save()`` is called on it.
|
||||
|
||||
In the context of Converse it might mean that there's an attempt to persist data before all models have been properly initialized,
|
||||
or conversely after models have been removed from their containing collections.
|
@ -1,62 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="no-js" lang="en">
|
||||
<head>
|
||||
<title>Converse</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js" />
|
||||
<link rel="shortcut icon" type="image/ico" href="/dist/favicon.ico"/>
|
||||
<script type="text/javascript" src="inverse-analytics.js"></script>
|
||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=5" style="border:0;" alt="" /></p></noscript>
|
||||
<link rel="manifest" href="./manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="/dist/converse.min.js"></script>
|
||||
</head>
|
||||
<body class="converse-fullscreen">
|
||||
<noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript>
|
||||
<div id="conversejs-bg"></div>
|
||||
<script>
|
||||
/*
|
||||
@licstart
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@licend
|
||||
*/
|
||||
converse.initialize({
|
||||
authentication: 'login',
|
||||
auto_away: 300,
|
||||
auto_reconnect: true,
|
||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||
message_archiving: 'always',
|
||||
view_mode: 'fullscreen'
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
10
html/404.html
Normal file
10
html/404.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Page Not Found</h2>
|
||||
|
||||
<p>
|
||||
The page you are looking for was not found.
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
12
html/500.html
Normal file
12
html/500.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Server Error</h2>
|
||||
|
||||
<p>
|
||||
The server had serious problems while serving your request. We've just sent our
|
||||
trained monkeys to fix the issue.
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
70
html/base.html
Normal file
70
html/base.html
Normal file
@ -0,0 +1,70 @@
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{{ LANGUAGE_CODE }}" lang="{{ LANGUAGE_CODE }}">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="author" content="Michal Čihař" />
|
||||
<meta name="copyright" content="Copyright © 2003 - {{ current_year }} Michal Čihař" />
|
||||
|
||||
<title>{% include "title.html" %}</title>
|
||||
{% if description %}
|
||||
<meta name="description" content="{{ description }}" />
|
||||
{% endif %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/media/css/style.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/media/css/blitzer/jquery-ui-1.8.18.custom.css" />
|
||||
<script src="/media/js/jquery-1.7.1.min.js" type="text/javascript"></script>
|
||||
<script src="/media/js/jquery-ui-1.8.18.custom.min.js" type="text/javascript"></script>
|
||||
<script src="/media/js/loader.js" type="text/javascript"></script>
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 class="ui-state-default"><a href="/">{% include "title.html" %}</a></h1>
|
||||
|
||||
<ul class="menu">
|
||||
{% if user.is_authenticated %}
|
||||
<li><a href="/accounts/profile/">{% blocktrans with user.get_full_name as name %}Logged in as {{ name }}{% endblocktrans %}</a></li>
|
||||
<li><a href="/accounts/logout/">{% trans "Logout" %}</a></li>
|
||||
{% else %}
|
||||
<li><a href="/accounts/register/">{% trans "Register" %}</a></li>
|
||||
<li><a href="/accounts/login/">{% trans "Login" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<ul class="breadcums">
|
||||
<li><a href="/">{% trans "Home" %}</a></li>
|
||||
{% block breadcums %}
|
||||
{% endblock %}
|
||||
</ul>
|
||||
|
||||
<div class="content">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="ui-widget">
|
||||
<div style="padding: 0pt 0.7em;" class="ui-state-{% if message.tags == "error" %}error{% else %}highlight{% endif %} ui-corner-all">
|
||||
<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-{% if message.tags == "error" or message.tags == "warning" %}alert{% else %}info{% endif %}"></span>
|
||||
{{ message }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<ul class="footer">
|
||||
<li>{% blocktrans %}Powered by <a href="http://weblate.org">Weblate {{ version }}</a>{% endblocktrans %}</li>
|
||||
<li><a href="{% url 'accounts.views.contact' %}">{% trans "Contact us" %}</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
18
html/contact.html
Normal file
18
html/contact.html
Normal file
@ -0,0 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% blocktrans %}Please contact us in English, otherwise we might be unable to understand your request.{% endblocktrans %}</p>
|
||||
|
||||
<form method="post" action="{% url 'accounts.views.contact' %}">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
<tr><td></td><td><input type="submit" class="button" value="{% trans "Send" %}" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
92
html/index.html
Normal file
92
html/index.html
Normal file
@ -0,0 +1,92 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if usertranslations %}
|
||||
<h2>{% trans "Your translations" %}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Language" %}</th>
|
||||
<th colspan="2">{% trans "Translated" %}</th>
|
||||
<th>{% trans "Fuzzy" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for trans in usertranslations %}
|
||||
{% with trans.get_translated_percent as percent and trans.get_fuzzy_percent as fuzzy %}
|
||||
<tr>
|
||||
<th><a href="{{ trans.get_absolute_url }}">{{ trans.subproject }} - {% trans trans.language.name %}</a></th>
|
||||
<td class="percent">{{ percent }}%</td>
|
||||
<td class="progress"><div class="progress" id="{{ percent|floatformat:0 }}"></div></td>
|
||||
<td class="percent">{{ fuzzy }}%</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
<h2>{% trans "Projects" %}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Project" %}</th>
|
||||
<th colspan="2">{% trans "Translated" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for prj in projects %}
|
||||
{% with prj.get_translated_percent as percent %}
|
||||
<tr>
|
||||
<th><a href="{{ prj.get_absolute_url }}">{{ prj.name }}</a></th>
|
||||
<td class="percent">{{ percent }}%</td>
|
||||
<td class="progress"><div class="progress" id="{{ percent|floatformat:0 }}"></div></td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>{% trans "Users" %}</h2>
|
||||
|
||||
<h3>{% trans "Best translators" %}</h3>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Translated" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for u in top_translations %}
|
||||
<tr>
|
||||
<td>{{ u.user.get_full_name }}</td>
|
||||
<td class="percent">{{ u.translated }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>{% trans "Best suggestions" %}</h3>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Suggested" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for u in top_suggestions %}
|
||||
<tr>
|
||||
<td>{{ u.user.get_full_name }}</td>
|
||||
<td class="percent">{{ u.suggested }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
43
html/profile.html
Normal file
43
html/profile.html
Normal file
@ -0,0 +1,43 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if form.errors or userform.errors %}
|
||||
<div class="ui-widget">
|
||||
<div style="padding: 0pt 0.7em;" class="ui-state-error ui-corner-all">
|
||||
<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>
|
||||
{% trans "Please fix errors in the form." %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="{% url 'accounts.views.profile' %}">
|
||||
{% csrf_token %}
|
||||
<div class="accordion">
|
||||
<h2><a href="#">{% trans "Preferences" %}</a></h2>
|
||||
<div>
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
</div>
|
||||
<h2><a href="#">{% trans "Account" %}</a></h2>
|
||||
<div>
|
||||
<table>
|
||||
{{ userform.as_table }}
|
||||
</table>
|
||||
<span class="helptext">{% trans "Your name and email will appear as author on Git commits." %}</span>
|
||||
</div>
|
||||
<h2><a href="#">{% trans "Password" %}</a></h2>
|
||||
<div>
|
||||
{% url 'django.contrib.auth.views.password_change' as pw_url %}
|
||||
{% blocktrans %}You can change password on <a href="{{ pw_url }}">separate page</a>.{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="{% trans "Save" %}" class="button" />
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
33
html/project.html
Normal file
33
html/project.html
Normal file
@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block breadcums %}
|
||||
<li><a href="{{ object.get_absolute_url }}">{{ object }}</a></li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "project_info.html" %}
|
||||
|
||||
<h2>{% trans "Subprojects" %}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Subproject" %}</th>
|
||||
<th colspan="2">{% trans "Translated" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for prj in object.subproject_set.all %}
|
||||
{% with prj.get_translated_percent as percent %}
|
||||
<tr>
|
||||
<th><a href="{{ prj.get_absolute_url }}">{{ prj.name }}</a></th>
|
||||
<td class="percent">{{ percent }}%</td>
|
||||
<td class="progress"><div class="progress" id="{{ percent|floatformat:0 }}"></div></td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
11
html/project_info.html
Normal file
11
html/project_info.html
Normal file
@ -0,0 +1,11 @@
|
||||
{% load i18n %}
|
||||
<h2>{% trans "Project Information" %}</h2>
|
||||
|
||||
<p>{% trans "Project website:" %} <a href="{{ object.web }}">{{ object.web }}</a></p>
|
||||
{% if object.mail %}
|
||||
<p>{% trans "Mailing list for translators:" %} <a href="mailto:{{ object.mail }}">{{ object.mail }}</a></p>
|
||||
{% endif %}
|
||||
{% if object.instructions %}
|
||||
<p>{% trans "Instructions for translators:" %} <a href="{{ object.instructions }}">{{ object.instructions }}</a></p>
|
||||
{% endif %}
|
||||
|
36
html/registration/activate.html
Normal file
36
html/registration/activate.html
Normal file
@ -0,0 +1,36 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if account %}
|
||||
<p>
|
||||
{% blocktrans with account.username as username %}Thank you. Your
|
||||
account is now activated. Your username is
|
||||
<b>{{ username }}</b>.{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% url 'accounts.views.profile' as profile_url %}
|
||||
{% blocktrans %}You might want to <a href="{{ profile_url }}">adjust your profile</a> now.{% endblocktrans %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
{% url 'registration.views.register' as reg_url %}
|
||||
{% blocktrans count expiration_days as days %}
|
||||
Your account could not be activated.
|
||||
This may be because it is already active or because you waited over
|
||||
{{ days }} day to activate it.
|
||||
If this is not the case, please contact the website administrator.
|
||||
Otherwise, you may <a href="{{ reg_url }}">register again.</a>
|
||||
{% plural %}
|
||||
Your account could not be activated.
|
||||
This may be because it is already active or because you waited over
|
||||
{{ days }} days to activate it.
|
||||
If this is not the case, please contact the website administrator.
|
||||
Otherwise, you may <a href="{{ reg_url }}">register again.</a>
|
||||
{% endblocktrans %}.
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
18
html/registration/activation_email.txt
Normal file
18
html/registration/activation_email.txt
Normal file
@ -0,0 +1,18 @@
|
||||
{% load url from future %}{% load i18n %}{% load weblate %}{% filter wordwrap:72 %}{% blocktrans with site|site_title as site_title %}Hi,
|
||||
|
||||
This is an automatic email to help you complete your registration
|
||||
with {{ site_title }}.
|
||||
|
||||
Please open the following link in your web browser. If the link
|
||||
is split over several lines, you may need to copy it in the
|
||||
address bar.{% endblocktrans %}
|
||||
|
||||
http://{{ site.domain }}{% url 'registration.views.activate' activation_key=activation_key %}
|
||||
|
||||
{% blocktrans with site|site_title as site_title %}
|
||||
If there is a problem with your registration, please reply to
|
||||
this email.
|
||||
|
||||
Best regards,
|
||||
{{ site_title }}
|
||||
{% endblocktrans %}{% endfilter%}
|
1
html/registration/activation_email_subject.txt
Normal file
1
html/registration/activation_email_subject.txt
Normal file
@ -0,0 +1 @@
|
||||
{% load i18n %}{% load weblate %}{% blocktrans with site|site_title as site_title %}Your registration on {{ site_title }}{% endblocktrans %}
|
44
html/registration/login.html
Normal file
44
html/registration/login.html
Normal file
@ -0,0 +1,44 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if form.errors %}
|
||||
<div class="ui-widget">
|
||||
<div style="padding: 0pt 0.7em;" class="ui-state-error ui-corner-all">
|
||||
<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>
|
||||
{% trans "Your username and password didn't match. Please try again." %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
<tr>
|
||||
<td>{{ form.username.label_tag }}</td>
|
||||
<td>{{ form.username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ form.password.label_tag }}</td>
|
||||
<td>{{ form.password }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="submit" value="{% trans "Login" %}" class="button" />
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
|
||||
<p>
|
||||
{% url 'registration.views.register' as register_url %}
|
||||
{% blocktrans %}Do not have an account yet? You can <a href="{{ register_url }}">register</a>.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{% url 'auth_password_reset' as reset_url %}
|
||||
{% blocktrans %}Forgot your password? You can <a href="{{ reset_url }}">reset it</a>.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
12
html/registration/logout.html
Normal file
12
html/registration/logout.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% blocktrans %}Thanks for using Weblate!{% endblocktrans %}</p>
|
||||
|
||||
<p><a href="{% url 'django.contrib.auth.views.login' %}">{% trans "Login again" %}</a></p>
|
||||
|
||||
{% endblock %}
|
||||
|
8
html/registration/password_change_done.html
Normal file
8
html/registration/password_change_done.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans 'Your password was changed.' %}</p>
|
||||
|
||||
{% endblock %}
|
26
html/registration/password_change_form.html
Normal file
26
html/registration/password_change_form.html
Normal file
@ -0,0 +1,26 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="ui-widget">
|
||||
<div style="padding: 0pt 0.7em;" class="ui-state-error ui-corner-all">
|
||||
<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>
|
||||
{% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<input type="submit" value="{% trans 'Change my password' %}" class="button" />
|
||||
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
10
html/registration/password_reset_complete.html
Normal file
10
html/registration/password_reset_complete.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
|
||||
|
||||
<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
|
||||
|
||||
{% endblock %}
|
23
html/registration/password_reset_confirm.html
Normal file
23
html/registration/password_reset_confirm.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if validlink %}
|
||||
|
||||
<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<input type="submit" value="{% trans 'Change my password' %}" class="button" />
|
||||
</form>
|
||||
|
||||
{% else %}
|
||||
|
||||
<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
9
html/registration/password_reset_done.html
Normal file
9
html/registration/password_reset_done.html
Normal file
@ -0,0 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
|
||||
|
||||
{% endblock %}
|
14
html/registration/password_reset_email.html
Normal file
14
html/registration/password_reset_email.html
Normal file
@ -0,0 +1,14 @@
|
||||
{% load i18n %}{% load url from future %}{% autoescape off %}
|
||||
{% blocktrans %}You're receiving this e-mail because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
|
||||
|
||||
{% trans "Please go to the following page and choose a new password:" %}
|
||||
{% block reset_link %}
|
||||
{{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %}
|
||||
{% endblock %}
|
||||
{% trans "Your username, in case you've forgotten:" %} {{ user.username }}
|
||||
|
||||
{% trans "Thanks for using our site!" %}
|
||||
|
||||
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||
|
||||
{% endautoescape %}
|
13
html/registration/password_reset_form.html
Normal file
13
html/registration/password_reset_form.html
Normal file
@ -0,0 +1,13 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
|
||||
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="{% trans 'Reset my password' %}" class="button" />
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
10
html/registration/registration_complete.html
Normal file
10
html/registration/registration_complete.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>{% blocktrans %}Thank you for registering. You will very soon receive an email with
|
||||
a confirmation link. Please follow this link in order to complete your registration.{% endblocktrans %}</p>
|
||||
|
||||
{% endblock %}
|
27
html/registration/registration_form.html
Normal file
27
html/registration/registration_form.html
Normal file
@ -0,0 +1,27 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if form.errors %}
|
||||
<div class="ui-widget">
|
||||
<div style="padding: 0pt 0.7em;" class="ui-state-error ui-corner-all">
|
||||
<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>
|
||||
{% trans "Please fix errors in registration form." %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form action="{% url 'weblate_register' %}" method="post" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<p>{% trans "By registering you agree to use your name and email in Git commits." %}</p>
|
||||
<p><input type="submit" value="{% trans 'Register' %}" class="button" /></p>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
41
html/subproject.html
Normal file
41
html/subproject.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
|
||||
{% block breadcums %}
|
||||
<li><a href="{{ object.project.get_absolute_url }}">{{ object.project }}</a></li>
|
||||
<li><a href="{{ object.get_absolute_url }}">{{ object.name }}</a></li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include "subproject_info.html" %}
|
||||
|
||||
<h2>{% trans "Translations" %}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Language" %}</th>
|
||||
<th colspan="2">{% trans "Translated" %}</th>
|
||||
<th>{% trans "Fuzzy" %}</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
{% for trans in object.translation_set.all %}
|
||||
{% with trans.get_translated_percent as percent and trans.get_fuzzy_percent as fuzzy %}
|
||||
<tr>
|
||||
<th><a href="{{ trans.get_absolute_url }}">{% trans trans.language.name %}</a></th>
|
||||
<td class="percent">{{ percent }}%</td>
|
||||
<td class="progress"><div class="progress" id="{{ percent|floatformat:0 }}"></div></td>
|
||||
<td class="percent">{{ fuzzy }}%</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% url 'accounts.views.contact' as contact_url %}
|
||||
|
||||
<p>{% blocktrans %}Should your language be missing, plese <a href="{{ contact_url }}?subject=New+language+request+for+{{ object }}">contact us</a>.{% endblocktrans %}</li>
|
||||
|
||||
{% endblock %}
|
||||
|
6
html/subproject_info.html
Normal file
6
html/subproject_info.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% with object.project as object %}
|
||||
{% include "project_info.html" %}
|
||||
{% endwith %}
|
||||
<p>{% trans "Git repository:" %} <code>{{ object.repo }}</code> ({% blocktrans with object.branch as branch %}{{ branch }} brach{% endblocktrans %})</p>
|
9
html/title.html
Normal file
9
html/title.html
Normal file
@ -0,0 +1,9 @@
|
||||
{% if title %}
|
||||
{{ title }} @ {{ site_title }}
|
||||
{% else %}
|
||||
{% if object %}
|
||||
{{ object }} @ {{ site_title }}
|
||||
{% else %}
|
||||
{{ site_title }}
|
||||
{% endif %}
|
||||
{% endif %}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user