Compare commits

..

No commits in common. "main-chapril-rebranding" and "3.3.2" have entirely different histories.

969 changed files with 182362 additions and 247727 deletions

9
.babelrc Normal file
View File

@ -0,0 +1,9 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 10", "IE >= 11"]
}
}]
]
}

View File

@ -1,35 +1,37 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"allowImportExportEverywhere": true
"ecmaVersion": 6
},
"env": {
"browser": true,
"jasmine": true,
"es6": true
"jasmine": true
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["lodash"],
"extends": ["eslint:recommended", "plugin:lodash/canonical"],
"globals": {
"Uint8Array": true,
"Promise": true,
"define": true,
"require": true,
"window": true,
"sinon": true,
"window": true
"define": true,
"require": true
},
"rules": {
"lodash/prefer-lodash-method": [2, {
"ignoreMethods": [
"find", "endsWith", "startsWith", "filter", "reduce",
"map", "replace", "toLower", "split", "trim", "forEach", "toUpperCase", "includes"
]
}],
"lodash/prefer-startswith": "off",
"lodash/prefer-constant": "off",
"lodash/prefer-noop": "off",
"lodash/prefer-lodash-typecheck": "off",
"lodash/preferred-alias": "off",
"lodash/prefer-get": "off",
"accessor-pairs": "error",
"array-bracket-spacing": "off",
"array-callback-return": "error",
"arrow-body-style": "off",
"arrow-parens": "off",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "error",
"block-scoped-var": "off",
"block-spacing": "off",
@ -55,7 +57,7 @@
"property"
],
"dot-notation": [
"off",
"error",
{
"allowKeywords": true
}
@ -64,7 +66,6 @@
"eqeqeq": "off",
"func-call-spacing": "off",
"no-spaced-func": "off",
"no-redeclare": "off",
"func-name-matching": "error",
"func-names": "off",
"func-style": "off",
@ -90,7 +91,7 @@
"max-depth": "error",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "off",
"max-nested-callbacks": "error",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "off",
@ -101,16 +102,16 @@
"newline-per-chained-call": "off",
"no-alert": "off",
"no-array-constructor": "error",
"no-await-in-loop": "off",
"no-await-in-loop": "error",
"no-bitwise": "off",
"no-caller": "error",
"no-console": "off",
"no-catch-shadow": "off",
"no-catch-shadow": "error",
"no-cond-assign": [
"off",
"error",
"except-parens"
],
"no-confusing-arrow": "off",
"no-confusing-arrow": "error",
"no-continue": "off",
"no-div-regex": "error",
"no-duplicate-imports": "error",
@ -148,7 +149,7 @@
"no-negated-condition": "off",
"no-negated-in-lhs": "error",
"no-nested-ternary": "off",
"no-new": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-require": "error",
@ -157,7 +158,7 @@
"no-param-reassign": "off",
"no-path-concat": "error",
"no-plusplus": "off",
"no-process-env": "off",
"no-process-env": "error",
"no-process-exit": "error",
"no-proto": "error",
"no-prototype-builtins": "error",
@ -184,11 +185,10 @@
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "off",
"no-unused-vars": "error",
"no-unused-vars": "off",
"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",
@ -203,7 +203,7 @@
"object-curly-newline": "off",
"object-curly-spacing": "off",
"object-property-newline": [
"off",
"error",
{
"allowMultiplePropertiesPerLine": true
}
@ -212,7 +212,10 @@
"one-var": "off",
"one-var-declaration-per-line": "off",
"operator-assignment": "off",
"operator-linebreak": "off",
"operator-linebreak": [
"error",
"after"
],
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "error",
@ -224,7 +227,7 @@
}
],
"prefer-numeric-literals": "error",
"prefer-promise-reject-errors": "off",
"prefer-promise-reject-errors": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
@ -235,13 +238,12 @@
"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-imports": "error",
"sort-keys": "off",
"sort-vars": "off",
"space-before-blocks": "off",
@ -252,7 +254,7 @@
"spaced-comment": "off",
"strict": "off",
"symbol-description": "error",
"template-curly-spacing": "off",
"template-curly-spacing": "error",
"unicode-bom": [
"error",
"never"

View File

@ -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.

37
.github/CONTRIBUTING.rst vendored Normal file
View File

@ -0,0 +1,37 @@
=======================
Contribution Guidelines
=======================
Thanks for contributing to `Converse.js <http://conversejs.org>`_.
Support questions
=================
Please ask support and setup questions on the mailing list: conversejs@librelist.com
The issue tracker is only for bugs (i.e. issues) and feature requests.
Contributing Code
=================
Please follow the usual github workflow. Create your own local 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. We use Jasmine
for testing.
Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
to see how tests are implemented.
Check that the tests pass
~~~~~~~~~~~~~~~~~~~~~~~~~
Check that all tests complete sucessfully.
Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
in your browser.

4
.github/FUNDING.yml vendored
View File

@ -1,4 +0,0 @@
# These are supported funding model platforms
patreon: jcbrand
liberapay: jcbrand

View File

@ -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.

View File

@ -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.

View File

@ -2,7 +2,7 @@ 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`
- [ ] Add a changelog entry for your change in `docs/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

View File

@ -1,2 +0,0 @@
paths-ignore:
- '**/tests/*.js'

View File

@ -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

View File

@ -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 }}"

View File

@ -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

46
.gitignore vendored
View File

@ -1,16 +1,9 @@
# Distribution directory
dist
# conversejs/media repo checkout
media
# Editor fluff
*~
.sw?
*.mo
*.kpf
.*.sw?
.*.cfg
.hg/
.bzr/
.svn/
@ -18,37 +11,34 @@ media
.pydevproject
.idea
.su?
.sass-cache
pip-selfcheck.json
3rdparty/libsignal-protocol-javascript/
*.map
locale.zip
sounds.zip
builds/*
analytics.js
inverse-analytics.js
# virtualenv/python/buildout
.*.cfg
# python/buildout
eggs
.Python
build
share
parts
*.pyc
*.egg-info
lib
lib64
include
bin
develop-eggs
pyvenv.cfg
dev-jc.html
inverse-dev.html
inverse-dev-jc.html
converse-logs/*.html
# Ruby/Sass/Bundler
.bundle
.sass-cache
ruby
bourbon
Backbone.Overview
tags
stamp-npm
stamp-bundler
transpile
# Sphinx
@ -58,6 +48,12 @@ docs/doctrees
# Node.js
node_modules
# Virtualenv/Buildout
lib
include
bin
develop-eggs
# OSX
.DS_Store

1
.nvmrc
View File

@ -1 +0,0 @@
v18.15.0

View File

@ -1,7 +0,0 @@
{
"printWidth": 120,
"quoteProps": "preserve",
"singleQuote": true,
"spaceBeforeFunctionParen": true,
"tabWidth": 4
}

13
.travis.yml Normal file
View File

@ -0,0 +1,13 @@
dist: trusty
language: node_js
cache:
directories:
- node_modules
addons:
chrome: stable
node_js:
- 6
install: make stamp-npm
before_script: make serve_bg
script: make check
sudo: false

1708
3rdparty/bigint.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1042
3rdparty/lodash.fp.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,902 +1,5 @@
# Changelog
## 10.1.6 (2023-08-31)
- #3246: Badge color not responsive to dark theme
- Fix a GIF rendering bug that causes a memory overflow
## 10.1.5 (2023-06-29)
- #3209: Fix error when importing the `converse` global with bootstrap modal API
- #3207: `.po` translation files weren't included in previous release
- Updated Galician and Portuguese translations
## 10.1.4 (2023-06-25)
- Fix `dist` directory not included in NPM package
## 10.1.3 (2023-06-23)
- Add the ability to set roles and affiliations via the MUC occupant modal
- Fix `isOnlyEmojis is not a function` when using only `@converse/headless`
- Fix `autojoin` checkbox state in MUC bookmark form
- Remove call to `api.confirm` in `@converse/headless`
- Generate TypeScript declaration files into `dist/types`
- Removed documentation about the no longer implemented `fullname` option.
- Updated translations
- #3123: Contacts do not show up online until chat is opened with them.
- #3156: Add function to prevent drag stutter effect over iframes when resize is called in overlay mode
- #3165: Use configured nickname in profile view in the control box
- New config option [stanza_timeout](https://conversejs.org/docs/html/configuration.html#stanza-timeout)
## 10.1.2 (2023-02-17)
- #1490: Busy-loop when fetching registration form fails
- #1556: Can't switch to registration form afrer logout
- #3137: Various UI/UX bugfixes regarding the registration form
- XEP-0437: Room Activity Indicators (RAI) optimizations
## 10.1.1 (2023-02-15)
- #1851: Sort open groupchats alphabetically
- #2240: Ad-Hoc command result form not shown
- #3128: Second bookmarked room shows info of the first one
- Bugfix. Uyghur translations weren't loading
## 10.1.0 (2023-01-07)
- #326: Add the ability to reset your password
- #2759: Don't automatically log in again if the user manually logged out
- #2816: Chat highlight behaves odd
- #2925: File upload is not always enabled
- #3001: Add option to save SCRAM details and to use them to stay logged in upon reload
- Add a "Add to Contacts" button in MUC occupant modals
- Updated translations and add support for Uyghur
- New config option [reuse_scram_keys](https://conversejs.org/docs/html/configuration.html#reuse-scram-keys)
## 10.0.0 (2022-10-30)
- Update to Strophe.js 1.6.0 which adds support for SCRAM-SHA-256 and SCRAM-SHA-512
- Don't automatically convert OpenStreetMap URLs into `geo:` URIs in sent messages
- Remove the `allow_chat_pending_contacts` config option.
- Show roster contacts with `subscription` set to `none`
- Remove the `converse-carbons` plugin and make carbons part of the `converse-chat` plugin.
- Remove the `message_carbons` configuration setting. Carbons are now always enabled.
- Move the `converse-oauth` plugin to the [community-plugins](https://github.com/conversejs/community-plugins)
- Don't apply message corrections when the MUC occupant-id doesn't match.
- Update `nick` attribute on ChatRoom when user nickname changes
- Restrict editing of MUC messages to ones with the same XEP-0421 occupant ID
- Remove unfurls for links removed in a subsequent message correction
- Bookmarks now appear in a modal and the `hide_open_bookmarks` config setting has been removed.
- #1004: Stop using fonts to render icons and use SVG instead
- #2797: Weird unicode characters rendering outside of line-height
- #2870: Fix for multiple URLs to be linkified when sent together in chat and adds a test for this.
- #2879: Quotes, lines not aligned to the first line
- #2925: Fix missing disco-items in browser storage.
- #2936: Fix documentation about enable_smacks option, which is true by default.
- #2939: Data forms with a field named "username" are not displayed
- #3005: Fix MUC messages with a fallback body not rendering.
- #3007: Fix links becoming text when a message is edited
- #3018: Fix MUC icons not functioning.
- #3028: Fix encrypted media from Conversations/Quicksy not properly decrypting
## 9.1.1 (2022-05-05)
- GIFs don't render inside unfurls and cause a TypeError
- Improve how the `muc_domain` setting is populated via service discovery
- Remove local (non-requesting) contacts not returned from a full roster response
- Improve performance by looking up VCards via map instead of traversing an array
- Fix infinite loop when receiving service discovery entities with a circular dependency
- #1130: Display the rooms vCard-temp avatar
- #2746: Always reply to all iqs, even those not understood
- #2794: Some display problems with mobile view mode
- #2868: Selected emoji is inserted into all open chat boxes
Remove the very old and largely unused config option `allow_muc`.
If you don't want MUC support, you can add `'converse-muc'` to the
`blacklisted_plugins` setting.
## 9.1.0 (2022-04-02)
- Updated translations: af, ar, es, eu, fr, gl, he, lt
- Increased stanza timeout from 10 to 20 seconds
- Replace various font icons with SVG icons
- Fix bug where MUC config wasn't persisted across page loads
- Add support for calling the IndexedDB `getAll` method to speed up fetching models from storage.
- #1761: Add a new dark theme based on the [Dracula](https://draculatheme.com/) theme
- #2557: Allow OMEMO encrypted messages to be edited
- #2627: Spoiler toggles only after switching to another tab and back
- #2733: Fix OMEMO race condition related to automatic reconnection and SMACKS
- #2733: Wait for decrypted/parsed message before queuing to UI
- #2751: Media not rendered when Converse runs in a browser extension
- #2754: Navigation keys doesn't work anymore into chat input message
- #2781: Flashing error when connecting to a room
- #2786: Fix webpack configuration not working on Windows OS
- #2788: `TypeError` when trying to use `@converse/headless`
- #2789: Implement new hook `parseMessageForCommands` for plugins to add custom commands
- #2814: Links are mangled on open/copy
- #2822: Singleton doesn't work in overlayed view mode
- New config option [show_connection_url_input](https://conversejs.org/docs/html/configuration.html#show-connection-url-input)
## 9.0.0 (2021-11-26)
- Compress new avatar images before uploading them
- Add initial support for XEP-0421 occupant Ids.
- Use more specific types for form fields based on XEP-0122
- Fix trimming of chats in overlayed view mode
- OMEMO bugfix: Always create device session based on real JID.
- If `auto_register_muc_nickname` is set, make sure to register when the user changes current nick.
- #1322: Display occupants avatars in the occupants list
- #1419: Clicking on avatar should show bigger version
- #1426: Don't fetch member list if not affiliated
- #2423: Could not find dependency "converse-controlbox" for plugin "converse-muc"
- #2640: Add `beforeFetchLoginCredentials` hook
- #2647: Singleton mode doesn't work
- #2650: Clicking on occupant in sidebar should add nickname to textarea
- #2683: Show error messages that don't refer to specific chat messages
- #2704: Send button doesn't work in a multi-user chat
- #2715: Singleton + fullscreen mode styling issue
- #2718: Message is not displayed if it contains an invalid URL
- #2725: Send new presence status to all connected MUCs
- #2728: Not sending headers with upload request
- #2733: OMEMO Messages received while client closed not decrypted
- Emit a `change` event when a configuration setting changes
- 3 New configuration settings:
- [render_media](https://conversejs.org/docs/html/configuration.html#render-media)
- [allowed_audio_domains](https://conversejs.org/docs/html/configuration.html#allowed-audio-domains)
- [allowed_video_domains](https://conversejs.org/docs/html/configuration.html#allowed-video-domains)
- [allowed_image_domains](https://conversejs.org/docs/html/configuration.html#allowed-image-domains)
Three config settings have been obsoleted:
- embed_audio
- embed_video
- show_images_inline
- muc_show_ogp_unfurls
### Breaking Changes
Configuration settings are no longer available on the `_converse` object.
Instead, use `api.settings.get` and `api.settings.set`.
## 8.0.1 (2021-09-09)
- #2326: 404 for asset /logo/conversejs-filled.svg
- #2628: Open groupchats toggle emits an error
- #2629: OMEMO button tooltip is wrong in private chat
- #2633: Excessive logging of warning
- #2634: Image previews not loading when not serving Converse locally
- #2636: Don't fail when setting up a new XEP-0198 managed stream and `_converse.session` is undefined
- Bugfix: Don't show minimized chats when logged out
## 8.0.0 (2021-09-03)
- Requires Node 12 or above
### Issues and features
- #1083: Add support for XEP-0393 Message Styling
- #1182: Add support for XEP-0454 OMEMO Media sharing
- #1823: New config options [mam_request_all_pages](https://conversejs.org/docs/html/configuration.html#mam-request-all-pages)
- #2275: Allow punctuation to immediately precede a mention
- #2348: `auto_join_room` not showing the room in `fullscreen` `view_mode`.
- #2400: Fixes infinite loop bug when appending .png to allowed image urls
- #2409: Integrate App Badging API for unread messages
- #2464: New configuration setting [allow_url_history_change](https://conversejs.org/docs/html/configuration.html#allow-url-history-change)
- #2497: Bugfix /nick command is not working
- Add a Description Of A Project (DOAP) file
- Add ability to deregister nickname when closing a MUC by setting `auto_register_muc_nickname` to `'unregister'`.
- Add support for XEP-0437 Room Activity Indicators see [muc-subscribe-to-rai](https://conversejs.org/docs/html/configuration.html#muc-subscribe-to-rai)
- Add support for rendering unfurls via [mod_ogp](https://modules.prosody.im/mod_ogp.html)
- Bugfix: Connection protocol not updated based on XEP-0156 connection methods
- Bugfix: Use real JID in XEP-0372 references only when the MUC is non-anonymous
- Bugfix: `null` inserted by emoji picker and can't switch between skintones
- File structure reordering: All plugins are now in `./plugins` folders.
- Show a gap placeholder when there are gaps in the chat history. The user can click these to fill the gaps.
- Use the MUC stanza id when sending XEP-0333 markers
- Add support for pausing Gif images
- Add limited support for XEP-0316 MUC notifications
### New configuration setings
- [show_tab_notifications](https://conversejs.org/docs/html/configuration.html#show-tab-notifications)
- [muc_clear_messages_on_leave](https://conversejs.org/docs/html/configuration.html#muc-clear-messages-on-leave)
- [send_chat_markers](https://conversejs.org/docs/html/configuration.html#send-chat-markers)
- [muc_show_ogp_unfurls](https://conversejs.org/docs/html/configuration.html#muc-show-ogp-unfurls)
- [prune-messages-above](https://conversejs.org/docs/html/configuration.html#prune-messages-above)
- [pruning_behavior](https://conversejs.org/docs/html/configuration.html#pruning-behavior)
### New hooks and events
- New hook: [getMessageActionButtons](https://conversejs.org/docs/html/api/-_converse.html#event:getMessageActionButtons)
- New hook: [shouldNotifyOfGroupMessage](https://conversejs.org/docs/html/api/-_converse.html#event:shouldNotifyOfGroupMessage)
- New hook: [presenceConstructed](https://conversejs.org/docs/html/api/-_converse.html#event:presenceConstructed)
- New event: [historyPruned](https://conversejs.org/docs/html/api/-_converse.html#event:historyPruned)
### Breaking Changes
The default persistent store, set via the [persistent_store](https://conversejs.org/docs/html/configuration.html#persistent-store),
is now IndexedDB. This main advantage of using IndexedDB is that it doesn't
have a fixed size limit. We don't provide a tool to migrate data from
localStorage to IndexedDB. For almost all data this is not a problem since
the data can be fetched again from the XMPP server. However,
decrypted OMEMO messages cannot be fetched again from the server, since the
double ratchet makes it impossible to again decrypt them. This means your
decrypted OMEMO history will be lost in the transition.
The [afterMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:afterMessageBodyTransformed) and [beforeMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:beforeMessageBodyTransformed) events now has a different signatures.
When leaving a MUC, the message history is deleted. This means that decrypted
OMEMO messages are gone and cannot be recovered on that device. See [muc_clear_messages_on_leave](https://conversejs.org/docs/html/configuration.html#muc-clear-messages-on-leave).
Removed events:
* `bookmarkViewsInitialized`
* `chatBoxInsertedIntoDOM`
* `contactStatusMessageChanged`
* `messageSend` (use `sendMessage` instead)
* `rosterGroupsFetched`
The `chatBoxClosed`, `chatBoxMaximized` and `chatBoxMinimized` events now have the `model` as
payload and not the `view`.
The `api.chatviews` and `api.roomviews` API groupings and methods have been
removed. The original "views" don't really exist anymore, the UI is now composed web
components which should update reactively based on changes made on the models.
## 7.0.6 (2021-06-11)
- #2500: Wrong assignment in OMEMO code
## 7.0.5 (2021-03-16)
- #2377: The @converse/headless NPM package is missing the dist directory, causing import errors
- #2396: @converse/headless wrongly depends on `CustomElement` from the view layer
- #2381: Converse does not reflect the browser language
## 7.0.4 (2020-12-09)
Bugfix: Set protocol after discovering connection methods
Otherwise if an endpoint was passed in with `converse.initialize`, then
that endpoint's protocol is (potentially wrongly) used.
## 7.0.3 (2020-12-02)
- Bugfix: `null` inserted by emoji picker and can't switch between skintones
## 7.0.2 (2020-11-23)
- Updated translations: de, nb, gl, tr
- Still more necessary files not included in the 7.0.1 NPM package, causing `Module not found` errors.
- #2337: Newly opened headline chat isn't hidden by default
## 7.0.1 (2020-11-19)
- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh
- #2328: Honor `use_system_emojis` in emoji-picker
- Not all template/*.js files were included in the 7.0.0 NPM package, causing:
`Module not found: Error: Can't resolve 'templates/*.js'`
## 7.0.0 (2020-11-18)
*Note for plugin authors:*
configuration settings should now be accessed via `_converse.api.settings.get` and not directly on the `_converse` object.
Soon we'll deprecate the latter, so prepare now.
- #515 Add support for XEP-0050 Ad-Hoc commands
- #2231: add sort_by_query and remove sort_by_length
- #1313: Stylistic improvements to the send button
- #1481: MUC OMEMO: Error No record for device
- #1490: Busy-loop when fetching registration form fails
- #1535: Add option to destroy a MUC
- #1715: Update chat state notification after receiving a message correction.
- #1793: Send button doesn't appear in Firefox in 1:1 chats
- #1820: Set focus on jid field after controlbox is loaded
- #1822: Don't log error if user has no bookmarks
- #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy)
and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint)
- #1826: A user can now add himself as a contact
- #1839: Headline messages are shown in controlbox
- #1924: Configuring an ejabberd room fails
- #1896: Don't send receipts for messages fetched from the archive
- #1937: Editing a message removes the mentions highlight
- #1963: Mentions are visually incorrect when used in message replies
- #1999: Demarcate first unread message
- #2002: fix rendering of `muc_roomid_policy_hint`
- #2006: fix rendering of emojis in case `use_system_emojis == false`
- #2028: Implement XEP-0333 `displayed` chat marker
- #2101: Improve contrast of text in control box
- #2187: Avoid merging initial settings with themselves every time settings are extended.
- #2199: Fix BOSH session restore.
- #2201: added html to converse.env
- #2213: added CustomElement to converse.env
- #2220: fix rendering of emojis in case `use_system_emojis == false` (again).
- #2092: fixes room list update loop when having the `locked_muc_domain` truthy or `'hidden'`
- #2259: Rename configuration setting `muc_show_join_leave` to `muc_show_info_messages`. Now accepts a list of events to show instead of a boolean.
- #2285: Rename config option `muc_hats_from_vcard` to [muc_hats](https://conversejs.org/docs/html/configuration.html#muc-hats). Now accepts a list instead of a boolean and allows for more flexible choices regarding user badges.
- #2300: Fix message reorder issue after message correction.
- #2304: Custom emojis (stickers) images not shown
- #2307: BootstrapModal is not accessible to plugins
- #2308: Allow getHats method to be overriden in the `overrides` object in plugins.
- #2321: When Converse runs inside a browser extension, enable browser sync and local storage for persistent storage
- #1250: Change favicon color when unread messages
- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh
- The `trusted` configuration setting has been removed in favor of two new settings:
[allow_user_trust_override](https://conversejs.org/docs/html/configuration.html#allow-user-trust-override)
[clear_cache_on_logout](https://conversejs.org/docs/html/configuration.html#clear-cache-on-logout)
- The `persistent_store` setting can now also be set to `sessionStorage`
- The `api.archive.query` method no longer accepts an RSM instance as argument.
- The plugin `converse-uniview` has been removed and its functionality merged into `converse-chatboxviews`
- Removed the mockups from the project. Recommended to use tests instead.
- The API method `api.settings.update` has been deprecated in favor of `api.settings.extend`.
- The API methods under the `api.user.status` namespace are now asynchronous and need to be `await`ed.
- Filter roster contacts via all available information (JID, nickname and VCard full name).
- Allow ignoring of bootstrap modules at build using environment variable. For xample: `export BOOTSTRAP_IGNORE_MODULES="Modal,Dropdown" && make dist`
- Bugfix. Handle stanza that clears the MUC subject
- Replace Backbone with [Skeletor](https://github.com/skeletorjs/skeletor)
- Start using [lit-html](https://lit-html.polymer-project.org/) instead of lodash for templating.
- [muc_fetch_members](https://conversejs.org/docs/html/configuration.html#muc-fetch-members) now also accepts an array of affiliations to fetch.
- Remove the configuration setting `muc_show_join_leave_status`. The optional status message is no longer shown at all.
- Support for XEP-0156 is now enabled by default (which means that
[discover_connection_methods](https://conversejs.org/docs/html/configuration.html#discover-connection-methods) now has a default value of `true`).
- [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button) now has a default value of `true`.
- The [api.confirm](https://conversejs.org/docs/html/api/-_converse.api.html#.confirm) method now accepts a list of fields and returns the filled in list upon confirmation.
- New config option [allow_adhoc_commands](https://conversejs.org/docs/html/configuration.html#allow-adhoc-commands)
- New config option [modtools_disable_assign](https://conversejs.org/docs/html/configuration.html#modtools-disable-assign)
- New config option [modtools_disable_query](https://conversejs.org/docs/html/configuration.html#modtools-disable-query)
- New config option [muc_hats_from_vcard](https://conversejs.org/docs/html/configuration.html#muc-hats-from-vcard).
- New config option [muc_send_probes](https://conversejs.org/docs/html/configuration.html#muc-send-probes).
- New config option [notify_nicknames_without_references](https://conversejs.org/docs/html/configuration.html#notify-nicknames-without-references).
- New config option [show_message_avatar](https://conversejs.org/docs/html/configuration.html#show-message-avatar).
- New public API [converse.insertInto](https://conversejs.org/docs/html/api/converse.html#.insertInto)
## 6.0.0 (2020-01-09)
- [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) is now set to `true` by default.
- Refactor some presence and status handling code from `converse-core` into `@converse/headless/converse-status`.
- It's now possible to navigate the emoji-picker via the keyboard arrow keys.
- Add support for [notifications about affiliation change for users not in a room](https://xmpp.org/extensions/xep-0045.html#example-196)
- Add support for [XEP-0424 Message Retraction](http://xmpps.org/extensions/xep-0424.html)
- Add support for [XEP-0425 Message Moderation](http://xmpps.org/extensions/xep-0425.html)
- New API [\_converse.api.headlines](https://conversejs.org/docs/html/api/-_converse.api.headlines.html#.get)
- New config option [allow_message_retraction](https://conversejs.org/docs/html/configuration.html#allow-message-retraction)
- New config option [muc-show-logs-before-join](https://conversejs.org/docs/html/configuration.html#muc-show-logs-before-join)
- New config option [muc_mention_autocomplete_filter](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-filter)
- New config option [muc_mention_autocomplete_show_avatar](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-show-avatar)
- New config option [persistent_store](https://conversejs.org/docs/html/configuration.html#persistent-store)
- Initial support for sending custom emojis. Currently only between Converse
instances. Still working out a wire protocol for compatibility with other clients.
To add custom emojis, edit the `emojis.json` file.
- #129: Add support for [XEP-0156: Disovering Alternative XMPP Connection Methods](https://xmpp.org/extensions/xep-0156.html). Only XML is supported for now.
- #1105: Support for storing persistent data in IndexedDB
- #1253: Show contacts with unread messages at the top of the roster
- #1322 Display occupants avatars in the occupants list
- #1640: Add the ability to resize the occupants sidebar in MUCs
- #1666: Allow scrolling of the OMEMO fingerprints list
- #1691: Fix `collection.chatbox is undefined` errors
- #1767: `credentials_url` is not called when logging out and then in again
- #1764: Incorrect URI encoding in "mention" references
- #1772: `_converse.api.contact.add(jid, nick)` fails, says not a function
- #1791: `auto_focus` set to `false` is ignored when switching back to a MUC
- #1792: Fix: modals don't have scrollbars
- #1796: Don't show "back" arrow navigation (on mobile) in the chat header when in `singleton` mode
- #1821: Errors caused by malformed URLs are now handled
- #1819: Click on a desktop notification now opens corresponding chat.
- #1836: MUC invites appear to come from the MUC name
### Breaking changes
- The ``debug`` configuration option has been replaced with [loglevel](https://conversejs.org/docs/html/configuration.html#loglevel).
- In contrast to sessionStorage and localStorage, IndexedDB is an asynchronous database.
A lot of code that relied on database access to be synchronous had to be
updated to work with asynchronous access via promises.
- In order to add support for XEP-0156, the XMPP connection needs to be created
only once we know the JID of the user that's logging in. This means that the
[connectionInitialized](https://conversejs.org/docs/html/api/-_converse.html#event:connectionInitialized)
event now fires much later than before. Plugins that rely on `connectionInitialized`
being triggered before the user's JID has been provided will need to be updated.
- The following API methods now return promises:
* `_converse.api.chats.get`
* `_converse.api.chats.create`
* `_converse.api.rooms.get`
* `_converse.api.rooms.create`
* `_converse.api.roomviews.close`
- Changes the events:
* The `chatBoxInitialized` event now triggers when a `_converse.ChatBox` (not the view) is opened.
* Renamed the old `chatBoxInitialized` to `chatBoxViewInitialized` and trigger only for `ChatBoxView` instances.
* Renamed `chatRoomOpened` event to `chatRoomViewInitialized`
* The order of certain events have now changed: `statusInitialized` is now triggered after `initialized` and `connected` and `reconnected`.
- `_converse.api.chats.get()` now only returns one-on-one chats, not the control box or headline notifications.
- The `show_only_online_users` setting has been removed.
- `_converse.api.alert.show` is now `_converse.api.show` and instead of taking
an integer for the `type`, "info", "warn" or "error" should be passed in.
- The `converse-headline` plugin has been split up into `converse-headlines` and `converse-headlines-view`.
## 5.0.5 (2019-11-20)
- Prevent editing of sent file uploads.
- #1089: When filtering the roster for `online` users, show all non-offline users.
- #1733: New message notifications for a minimized chat stack on top of each other
- #1757: Chats are hidden behind the controlbox on mobile
- #1760: Private messages no longer received after websocket reconnect
## 5.0.4 (2019-10-08)
- New config option [allow_message_corrections](https://conversejs.org/docs/html/configuration.html#allow-message-corrections)
which, if set to `last`, limits editing of sent messages to the last message sent.
- Bugfix: Don't treat every duplicate message ID as a message correction; since some clients don't use globally unique ID's this causes false positives.
- Bugfix: process stanzas from mam one-by-one in order to correctly process message receipts
- #1712: `TypeError: plugin._features is not a function`
- #1714: Don't notify the user in case we're receiving a message delivery receipt only
- #1739: New config option [assets_path](https://conversejs.org/docs/html/configuration.html#assets-path)
which lets you set the path from which "chunks" are loaded.
## 5.0.3 (2019-09-13)
- Emit `chatBoxFocused` and `chatBoxBlurred` events for emoji picker input
- SECURITY FIX: Reject unencapsulated forwarded messages, since we don't support XEP-0297 on its own
## 5.0.2 (2019-09-11)
- `po` translations files are now loaded via Webpack. As a result the `locales_url`
config option is now removed given that the path to the locale JSON files is now
determined by the webpack config and can't be changed at runtime.
- The JSON representing emojis is now fetched asynchronously as a separate file `converse.emojis.js`.
- Webpack is now configured with a `publicPath` set to `/dist/`. This is necessary
so that chunks (such as the emojis and locales JSON files) can be fetched asynchronously.
This means that all your assets need to be served at `/dist`. If you need to set a
different path, you'll need to set `publicPath` in `webpack.config.js` to
your preferred path and then rebuild all assets (e.g. `make dist`).
- Use `listenTo` to avoid memory leaks when views get removed.
- SECURITY FIX: Ignore MAM `chat` messages not sent from yourself
- #1692 Bugfix: `TypeError: oldest_message is undefined`
- #1704: SECURITY FIX: Impersonation by misusage of groupchat carbons
- #1705: Bugfix: `this.roomspanel` is `undefined` after hibernating
## 5.0.1 (2019-08-14)
- Add a new GUI for moderator actions. You can trigger it by entering `/modtools` in a MUC.
- Reconnect if the server doesn't respond to a `ping` within 10 seconds.
- Don't query for MAM MUC messages before the cached messages have been restored (another cause of duplicate messages).
- Show an error message and option to retry when fetching of the MAM archive times out
- Bugfix: `TypeError: o.getAttribute is not a function converse-chatview.js` (can cause messages to not appear).
- #1679: Room invitation fails with singleton and random server assigned room name
## 5.0.0 (2019-08-08)
- BOSH support has been moved to a plugin.
- Support for XEP-0410 to check whether we're still present in a room
- Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API
- Allow for synchronous events. When a synchronous event is fired, Converse will
wait for all promises returned by the event's handlers to finish before continuing.
- Properly handle message correction being received before the corrected message
- Groupchat default configuration now supports `list-multi` fields
- Bugfix: Don't set `muc_domain` for roomspanel if `locked_muc_domain` is `true`.
- Bugfix: Modal auto-closes when you open it for a second time.
- Bugfix: `Cannot read property 'parentElement' of null` in shadow DOM
- Take roster nickname into consideration when rendering messages and chat headings.
- Hide the textarea when a user is muted in a groupchat.
- Don't restore a BOSH session without knowing the JID
- In the `/help` menu, only show allowed commands
- Message deduplication bugfixes and improvements
- Continuously retry (in 2s intervals) to fetch login credentials (via [credentials_url](https://conversejs.org/docs/html/configuration.html#credentials-url)) in case of failure
- Replace `moment` with [DayJS](https://github.com/iamkun/dayjs).
- New config option [auto_focus](https://conversejs.org/docs/html/configuration.html#auto-focus)
- New config option [clear_messages_on_reconnection](https://conversejs.org/docs/html/configuration.html#clear-messages-on-reconnection)
- New config option [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks)
- New config option [message_limit](https://conversejs.org/docs/html/configuration.html#message-limit)
- New config option [muc_fetch_members](https://conversejs.org/docs/html/configuration.html#muc-fetch-members)
- New config option [muc_mention_autocomplete_min_chars](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-min-chars)
- New config option [muc_show_join_leave_status](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave-status)
- New config option [singleton](https://conversejs.org/docs/html/configuration.html#singleton)
By setting this option to `false` and `view_mode` to `'embedded'`, it's now possible to
"embed" the full app and not just a single chat. To embed just a single chat, it's now
necessary to explicitly set `singleton` to `true`.
- Re-add the previously removed config option [keepalive](https://conversejs.org/docs/html/configuration.html#keepalive)
- New event: [chatBoxBlurred](https://conversejs.org/docs/html/api/-_converse.html#event:chatBoxBlurred)
- New event: [chatReconnected](https://conversejs.org/docs/html/api/-_converse.html#event:chatReconnected)
- #316: Add support for XEP-0198 Stream Management
- #1071: x clear cross of same size as text
- #1142: Up/down arrow shouldn't erase current message
- #1196: Use alternative connection method upon connfail
- #1296: `embedded` view mode shows `chatbox-navback` arrow in header
- #1330: Missing room name in MUC invitation popup
- #1445: Participants list uses big font in embedded mode
- #1455: Avatar in controlbox status-view not updated
- #1465: When highlighting a roster contact, they're incorrectly shown as online
- #1476: Support OMEMO on by default for chats via a config variable
- #1494: Trim whitespace around messages
- #1495: Mentions should always include a URI attribute
- #1502: Fatal error when using prebind
- #1524: OMEMO libsignal-protocol.js Invalid signature
- #1532: Converse reloads on enter pressed in the filter box
- #1538: Allow adding self as contact
- #1548: Add support for paging through the MAM results when filling in the blanks
- #1550: Legitimate carbons being blocked due to erroneous forgery check
- #1554: Room auto-configuration broke if the config form contained fields with type `fixed`
- #1558: `this.get` is not a function error when `forward_messages` is set to `true`.
- #1561: Don't call `clear` on local or session storage
- #1572: In `fullscreen` view mode the top is cut off on iOS
- #1575: MUC invitation autocomplete list doesn't appear
- #1576: Converse gets stuck with spinner when logging out with `auto_login` set to `true`
- #1579: Trim spaces at the beginning and end of a JID (when adding contact)
- #1585: Upload files by pasting from clipboard
- #1586: Not possible to kick someone with a space in their nickname
- #1664: Blacklisting converse-profile makes the control box totally blank
### Breaking changes
- The minimum required NodeJS version for making builds is now 8.9.0
- Rename `muc_disable_moderator_commands` to [muc_disable_slash_commands](https://conversejs.org/docs/html/configuration.html#muc-disable-slash-commands).
- `_converse.api.archive.query` now returns a Promise instead of accepting a callback functions.
- `_converse.api.disco.supports` now returns a Promise which resolves to a Boolean instead of an Array.
- The `forward_messages` config option (which was set to `false` by default) has been removed.
Use [message_carbons](https://conversejs.org/docs/html/configuration.html#message-carbons) instead.
- Remove the `keepalive` configuration setting. It is now always implicitly `true`.
- Remove the `expose_rid_and_sid` configuration setting.
- A `prebind_url` is now mandatory when setting `authentication` to `prebind`.
It's no longer possible to pass in `rid` and `sid` values to `converse.initialize.
- Removed events `statusChanged` and `statusMessageChanged`. Instead, you can
listen on the `change:status` or `change:status\_message` events on
`_converse.xmppstatus`.
- #1403: Rename show_chatstate_notifications to show_chat_state_notifications
### API changes
- `_converse.chats.open` and `_converse.rooms.open` now take a `force`
parameter to force maximizing (in `overlayed` view mode) or bringing a
background chat into the foreground (in `fullscreen` view mode). Previously
this was the default behavior.
- `_converse.api.emit` has been removed in favor of [\_converse.api.trigger](https://conversejs.org/docs/html/api/-_converse.api.html#.trigger)
- `_converse.updateSettings` has been removed in favor of [\_converse.api.settings.update](https://conversejs.org/docs/html/api/-_converse.api.settings.html#.update)
- `_converse.api.roster.get` now returns a promise.
- New API method [\_converse.api.disco.features.get](https://conversejs.org/docs/html/api/-_converse.api.disco.features.html#.get)
- New API method [\_converse.api.connection.reconnect](https://conversejs.org/docs/html/api/-_converse.api.connection.html#.reconnect)
## 4.2.0 (2019-04-04)
**Note:** This release introduces a hard requirement on [MAM:2](https://xmpp.org/extensions/xep-0313.html),
specifically the requirement that the MAM archive ID matches the [XEP-0359 stanza-id](https://xmpp.org/extensions/xep-0359.html).
Patches intended to make Converse work with MAM:1 will cause problems and
unexpected behaviour due to the above requirement, which is not met with MAM:1.
This will affect OpenFire users who use the [monitoring plugin](https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=monitoring)
version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until an update to that plugin has been released.
- Updated translation: af, cz, de, es, gl, he, lt, nl, nl_BE, ru
- Upgrade to Backbone 1.4.0, Strophe 1.3.2 and Jasmine 2.99.2
- Remove dependency on (our fork of) Awesomplete
- Prevent user from adding themselves as contact
- Fix "flashing" of roster filter when you have less than 5 roster contacts
- Fix handling of CAPTCHAs offered by ejabberd
- Don't send out receipts or markers for MAM messages
- Allow setting of debug mode via URL with `/#converse?debug=true`
- Render inline images served over HTTP if Converse itself was loaded on an unsecured (HTTP) page.
- Make sure `nickname` passed in via `_converse.initialize` has first preference as MUC nickname
- Make sure required registration fields have "required" attribute
- New config setting [autocomplete_add_contact](https://conversejs.org/docs/html/configuration.html#autocomplete-add-contact)
- New config setting [locked_muc_domain](https://conversejs.org/docs/html/configuration.html#locked-muc-domain)
- New config setting [locked_muc_nickname](https://conversejs.org/docs/html/configuration.html#locked-muc-nickname)
- New config setting [show_client_info](https://conversejs.org/docs/html/configuration.html#show-client-info)
- Document new API method [sendMessage](https://conversejs.org/docs/html/api/-_converse.ChatBox.html#sendMessage)
- Don't filter out own device when sending an OMEMO message
- #1149: With `xhr_user_search_url`, contact requests are not being sent out
- #1213: Switch roster filter input and icons
- #1327: fix False mentions positives in URLs and Email addresses
- #1352: Add [Jed](https://github.com/messageformat/Jed) as dependency of `@converse/headless`
- #1373: Re-add support for the [muc_domain](https://conversejs.org/docs/html/configuration.html#muc-domain) setting
- #1400: When a chat message is just an emoji, enlarge the emoji
- #1407: Silent errors when trying to use whitespace as MUC nickname
- #1437: List of groupchats in modal doesn't scroll
- #1457: Wrong tooltip shown for "unbookmark" icon
- #1467: Fix rendering of URLs enclosed with sharp brackets such as <https://example.org>
- #1479: Allow file upload by drag & drop also in MUCs
- #1487: New config option [muc_respect_autojoin](https://conversejs.org/docs/html/configuration.html#muc-respect-autojoin)
- #1488: In error message, fall back to JID if name is not available.
- #1501: Don't prompt for a reason if [auto_join_on_invite](https://conversejs.org/docs/html/configuration.html#auto-join-on-invite) is `true`
- #1507: Make message id and origin-id identical in order to fix LMC with Conversations
- #1508: Minimized bookmarked chatboxes should not be always maximized after page reload.
- #1512: Allow manual entry of jid even with [xhr_user_search_url](https://conversejs.org/docs/html/configuration.html#xhr-user-search-url).
The JID input field is now also visible. To hide it simply hide `.add-xmpp-contact__jid` via CSS.
## 4.1.2 (2019-02-22)
- Updated translations: af, cz, de, es, he, it, nl, nl_BE, pt_BR, zh_CN
- Bugfix. Prevent duplicate messages by comparing MAM archive id to XEP-0359 stanza ids.
- Bugfix. Open groupchats not shown when logging in after disconnection.
- #1406: `TypeError: e.devicelists is undefined` when unchecking the "trusted device" checkbox
## 4.1.1 (2019-02-18)
- Updated translations: af, cz, de, es, eu, ga, he, hi, ja, nb, nl_BE, zh_CN
- New language supported: Esperanto
- Accessibility: Tag the chat-content as an ARIA live region, for screen readers
- Set releases URL to new Github repo
- Rudimentary support for XEP-0333 chat markers
- Better support for XEP-0359 `stanza-id` and `origin-id` elements.
- Bugfix: restore textarea size after sending a message
- Bugfix: MUC invite form not appearing
- #1369 Don't wrongly interpret message with `subject` as a topic change.
- #1405 Status of contacts list are not displayed properly
- #1408 New config option [roomconfig_whitelist](https://conversejs.org/docs/html/configuration.html#roomconfig-whitelist)
- #1410 HTTP upload not working if conversations push proxy is used
- #1412 MUC moderator commands can be disabled selectively by config
- #1413 Fix moderator commands that change affiliation
- #1414 Prevent duplicate messages on MUC join
- #1417 Margin between nickname and badge
- #1421 Fix direct invite for membersonly room
- #1422 Resurrect the `muc_show_join_leave` option
- #1438 Update contact nickname when receiving a roster push
- #1442 MUC read receipts causing empty lines
## 4.1.0 (2019-01-11)
- Bugfix: MUC commands were being ignored
- Bugfix: Multiple rooms shown active in the rooms list
- Bugfix: Don't open chats when receiving messages without a `body`
- Bugfix: Typing in the textarea can become very slow in large MUCs
- UI: Always show the OMEMO lock icon (grayed out if not available).
- Use `publish-options` with `pubsub#access_model` set to `open` when publishing OMEMO public keys and devices
- Add a new `converse-pubsub` plugin, for generic PubSub operations
- #1180 It's now possible to use OMEMO in a MUC (if it's members-only and non-anonymous)
- #1334 Force avatar refetch when receiving `vcard-temp:x:update`
- #1337 `send_chat_state_notifications` doesn't work in MUCs
- #1353 Message Delivery Receipts not working because of the message "type" attribute
- #1356 Make triangle icon usable
- #1374 Can't load embedded chat when changing `view_mode` between page reloads
- #1376 Fixed some alignment issues in the sidebar
- #1378 Message Delivery Receipts were being sent for carbons and own messages
- #1379 MUC unread messages indicator is failing
- #1382 Message Delivery Receipts: Set store hint and type='chat'
- #1388 implement muc-owner command `/destroy`
## 4.0.6 (2018-12-07)
- Updated translations: ar, cs, de, es, eu, fr, gl, hu, id, it, ja, nb, pt_BR
- Don't render http (i.e. non-TLS) resources
- Bugfix: Converse caused `RID out of range` errors on Prosody
- Bugfix: MUC messages sometimes appear twice after resync.
- #1331 Fix missing checkmarks in old muc messages
- #1333 Don't send receipt requests in MUCs
- #1348 Font gets cut off in Firefox #1348
## 4.0.5 (2018-11-15)
- Error `FATAL: TypeError: Cannot read property 'extend' of undefined` when using `embedded` view mode.
- Default paths in converse-notifications.js are now relative
- Add a button to regenerate OMEMO keys
- Add client info modal which shows Converse's version number
- New config setting [theme](https://conversejs.org/docs/html/configuration.html#theme)
- #141 XEP-0184: Message Delivery Receipts
- #1033 Setting show_send_button to true didn't work
- #1188 Feature request: drag and drop file to HTTP Upload
- #1268 Switch from SASS variables to CSS custom properties
- #1278 Replace the default avatar with a SVG version
- #1288 Add CSS classes to differentiate between incoming and outgoing messages
- #1305 added value 'all' for 'show_desktop_notifications' to notifiy even if converse.js is open
- #1306 added option `notification_delay`
- #1312 Error `unrecognized expression` in Safari
- #1316 show version info in login dialog
- #1317 Don't show errors for CSI messages
- #1318 added values 'on' and 'off' for 'trusted' option which removes the "This is a trusted device" checkbox from the login form
- #1319 Implement sending of presences according to XEP-0319: Last User Interaction in Presence
## 4.0.4 (2018-10-29)
- Use [Lerna](https://lernajs.io/) to create the @converse/headless package
- Use ES2015 modules instead of UMD.
- #1252 Correctly reflect the state in bookmark icon title.
- #1257 Prefer 'probably' over 'maybe' when evaluating audio play support.
- #1259 Don't inform of affiliation change after user leaves MUC
- #1261 File upload not working
- #1264 Right Align badges of room occupants
- #1272 Hiding MUC occupants leaves a blank space
- #1278 Replace the default avatar with a SVG version
## 4.0.3 (2018-10-22)
- New translations: Arabic, Basque, Czech, French, German, Hungarian, Japanese, Norwegian Bokmål, Polish, Romanian, Spanish
- Bugfix. Converse continuously publishes an empty OMEMO devicelist for itself
- Bugfix. Handler not triggered when submitting MUC password form 2nd time
- Bugfix. MUC features weren't being refreshed when saving the config form
- Don't show duplicate notification messages
- New config setting [show_images_inline](https://conversejs.org/docs/html/configuration.html#show-images-inline)
- Disable OMEMO when the user has indicated that Converse is running on an untrusted device.
- #537 Render `xmpp:` URI as link
- #1058 Send an inactive chat state notification when the user switches to another tab
- #1062 Collapse multiple join/leave messages into one
- #1063 URLs in the topic / subject are not clickable
- #1140 Add support for destroyed chatrooms
- #1169 Non-joined participants display an unwanted status message
- #1185 Added Contact still shown as pending
- #1190 MUC Participants column disappears in certain viewport widths
- #1193 OMEMO messages without a `<body>` fallback are ignored
- #1199 Can't get back from to login screen from registration screen
- #1204 Link encoding issue
- #1209 Bring color codes of users' status in line with other clients
- #1214 Setting `allow_contact_requests` to `false` has no effect
- #1221 Avoid creating a headlines box if we don't have anything to show inside it
- #1222 Adding a bookmark should prefill the room name
- #1228 Converse automatically visits links (to try and determine whether they're images to show inline)
## 4.0.2 (2018-10-02)
- M4A and WEBM files, when sent as XEP-0066 Out of Band Data, are now playable directly in chat
- Updated French and Spanish translations
- Two new languages supported, [Hindi](https://hosted.weblate.org/languages/hi/conversejs/) and [Romanian](https://hosted.weblate.org/languages/ro/conversejs/)
- #1176 Add config setting [send_chat_state_notifications](https://conversejs.org/docs/html/configuration.html#send-chat-state-notifications)
- #1187 UTF-8 characters have the wrong encoding when using OMEMO
- #1189 Video playback failure
- #1220 Converse not working in Edge
- #1225 User profile sometimes not displayed when libsignal-protocol.js is used
- #1227 Login form does not work in Epiphany
## 4.0.1 (2018-09-19)
- Use https://compliance.conversations.im instead of dead link tot st https://xmpp.net
- New config setting [auto_register_muc_nickname](https://conversejs.org/docs/html/configuration.html#auto-register-muc-nickname)
- New config setting [enable_muc_push](https://conversejs.org/docs/html/configuration.html#enable-muc-push)
- #1182 MUC occupants without nick or JID created
- #1184 Notification error when message has no body
- #1201 Emoji picker appears when pressing enter
## 4.0.0 (2018-09-07)
## New Features
- #161 XEP-0363: HTTP File Upload
- #194 Include entity capabilities in outgoing presence stanzas
- #337 API call to update a VCard
- #421 XEP-0308: Last Message Correction
- #497 XEP-0384: OMEMO encrypted messaging
- #968 Use nickname from VCard when joining a room
- #986 Affiliation changes aren't displayed in the chat
- #1081 Allow for shift-enter to insert newlines
- #1091 There's now only one CSS file for all view modes.
- #1094 Show room members who aren't currently online
- #1106 Support for Roster Versioning
- #1137 Autocompletion and support for [XEP-0372 References](https://xmpp.org/extensions/xep-0372.html), specifically section "3.2 Mentions".
- It's now also possible to edit your VCard via the UI
- Automatically grow/shrink input as text is entered/removed
- MP4 and MP3 files when sent as XEP-0066 Out of Band Data, are now playable directly in chat
- Support for rendering URLs sent according to XEP-0066 Out of Band Data.
- Geo-URIs (e.g. from Conversations) are now replaced by links to openstreetmap (works in reverse also)
- Add a checkbox to indicate whether a trusted device is being used or not.
If the device is not trusted, sessionStorage is used and all user data is deleted from the browser cache upon logout.
If the device is trusted, localStorage is used and user data is cached indefinitely.
- Initial support for [XEP-0357 Push Notifications](https://xmpp.org/extensions/xep-0357.html), specifically registering an "App Server".
- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configuration.html#oauth-providers) setting)
### Bugfixes
- Spoiler messages didn't include the message author's name.
- Documentation includes utf-8 charset to make minfied versions compatible across platforms. #1017
- #1026 Typing in MUC shows "Typing from another device"
- #1039 Multi-option data form elements not shown and saved correctly
- #1143 Able to send blank message
### API changes
- `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and
has an additional `force` parameter to force fetching the vcard even if it
has already been fetched.
- New API method `_converse.api.vcard.update`.
- The `contactStatusChanged` event has been renamed to `contactPresenceChanged`
and a event `presenceChanged` is now also triggered on the contact.
- `_converse.api.chats.open` and `_converse.api.rooms.open` now returns a
`Presence` which resolves with the `Backbone.Model` representing the chat
object.
## UI changes
- #956 Conversation pane should show my own identity in pane header
- The UI is now based on Bootstrap4 and Flexbox is used extensively.
- Fontawesome 5 is used for icons.
- User Avatars are now shown in chat messages.
## Configuration changes
- Removed the `storage` configuration setting, use [trusted](https://conversejs.org/docs/html/configuration.html#trusted) instead.
- Removed the `use_vcards` configuration setting, instead VCards are always used.
- Removed the `xhr_custom_status` and `xhr_custom_status_url` configuration
settings. If you relied on these settings, you can instead listen for the
[statusMessageChanged](https://conversejs.org/docs/html/events.html#contactstatusmessagechanged)
event and make the XMLHttpRequest yourself.
- Removed `xhr_user_search` in favor of only accepting `xhr_user_search_url` as configuration option.
- `xhr_user_search_url` has to include the `?` character now in favor of more flexibility. See example in the documentation.
- The data returned from the `xhr_user_search_url` must now include the user's
`jid` instead of just an `id`.
- New configuration settings [nickname](https://conversejs.org/docs/html/configuration.html#nickname)
and [auto_join_private_chats](https://conversejs.org/docs/html/configuration.html#auto-join-private-chats).
## Architectural changes
- Extracted the views from `converse-muc.js` into `converse-muc-views.js` and
where appropriate moved methods from the views into the models/collections.
This makes MUC possible in headless mode.
- Created a new core plugin `converse-roster.js` which contains the models for
roster-related data. Previously this code was in `converse-core.js`.
- VCards are now stored separately from chats and roster contacts.
## Other
- Support for OTR (off-the-record) encryption has been dropped.
## 3.3.4 (2018-03-05)
- Don't show bookmark toggles when PEP bookmarking not supported by the XMPP server.
- Emojis are now sent in unicode instead of short names (also in MUCs)
### Bugfixes
- Server field in `Rooms` tab showed MUC supporting clients instead of only components.
- Avatars weren't being shown.
- Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser).
- #1022 Status message not sent out on subsequent presences
- #1024 null reference on MUC Invite
- #1025 OTR lock icon disappears
- #1027 `new Event` not supported in IE11
- #1028 Avoid `eval` (crept in via `_.template` from lodash).
### Translation changes
- New locale: Bulgarian
- Updated German, Russian, Chinese (traditional), Norwegian Bokmål and French translations.
## 3.3.3 (2018-02-14)
### Bugfixes
- Attribute error when empty IQ stanza is returned for vCard query
- In fullscreen view, sometimes a background MUC would come into the foreground
when a new message appears inside it.
### Security fixes
- CVE-2018-6591: Don't allow PEP bookmarks if `pubsub#publish-options` is not advertised by the server.
In previous versions of converse.js, bookmarks sent to servers that don't
support `pubsub#publish-options` were visible to all your contacts, even
though they should be kept private. This is due to those servers simply
ignoring the `pubsub#publish-options` directive and converse.js not checking
first whether `pubsub#publish-options` is supported before setting bookmarks
via PEP.
More info here: https://gultsch.de/converse_bookmarks.html
### New features
- XEP-0382 Spoiler Messages (currently only for private chats)
- Listen for new room bookmarks pushed from the user's PEP service.
- Simplified the [embedded](https://conversejs.org/demo/embedded.html) usecase.
- No need to manually blacklist or whitelist any plugins.
- Relies on the [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) being set to `'embedded'`.
- The main `converse.js` build can be used for the embedded usecase.
- Maintain MUC session upon page reload
### API changes
- New API method `_converse.api.disco.getIdentity` to check whether a JID has a given identity.
### Configuration settings
- `auto_reconnect` is now set to `true` by default.
- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configuration.html#allow-public-bookmarks)
- New configuration setting [root](https://conversejs.org/docs/html/configuration.html#root)
- The [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) setting now has a new possible value: `embedded`
### Translation updates
- Chinese (Traditional), French, German, Portuguese (Brazil), Russian, Ukrainian
## 3.3.2 (2018-01-29)
### Bugfixes
@ -921,7 +24,7 @@ version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until
### UI/UX changes
- Add new configuration option
[show_message_load_animation](https://conversejs.org/docs/html/configuration.html#show-message-load-animation)
[show_message_load_animation](https://conversejs.org/docs/html/configurations.html#show-message-load-animation)
with a default value of `false`. The message load animations (added in 3.3.0)
cause slowness and performance issues in Firefox, so they're now disabled by default.
@ -958,7 +61,7 @@ version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until
and private chats with a URL fragment such as `#converse/chat?jid=user@domain`
- #828 Add routing for the `#converse/login` and `#converse/register` URL
fragments, which will render the registration and login forms respectively.
- New configuration setting [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode)
- New configuration setting [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode)
This removes the need for separate `inverse.js` and `converse-mobile.js`
builds. Instead the `converse.js` build is now used with `view_mode` set to
`fullscreen` and `mobile` respectively.
@ -996,7 +99,7 @@ version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until
- Converse.js no longer includes all the translations in its build. Instead,
only the currently relevant translation is requested. This results in a much
smaller filesize but means that the translations you want to provide need to
be available. See the [locales_url](https://conversejs.org/docs/html/configuration.html#locales-url)
be available. See the [locales_url](https://conversejs.org/docs/html/configurations.html#locales-url)
configuration setting for more info.
- The translation machinery has now been moved to a separate module in `src/i18n.js`.
- jQuery has been completely removed as a dependency (still used in tests though).
@ -1025,10 +128,10 @@ version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until
### New configuration settings
* The `visible_toolbar_buttons.emoticons` configuration option is now changed to `visible_toolbar_buttons.emoji`.
* [use_emojione](https://conversejs.org/docs/html/configuration.html#use-emojione)
* [use_emojione](https://conversejs.org/docs/html/configurations.html#use-emojione)
is used to determine whether Emojione should be used to render emojis,
otherwise rendering falls back to native browser or OS support.
* [emojione_image_path](https://conversejs.org/docs/html/configuration.html#emojione-image-path)
* [emojione_image_path](https://conversejs.org/docs/html/configurations.html#emojione-image-path)
is used to specify from where Emojione will load images for rendering emojis.
### New events
@ -1082,7 +185,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
### New configuration settings
- New setting for `converse-bookmarks`:
[hide_open_bookmarks](https://conversejs.org/docs/html/configuration.html#hide-open-bookmarks)
[hide_open_bookmarks](https://conversejs.org/docs/html/configurations.html#hide-open-bookmarks)
It is meant to be set to `true` when using `converse-roomslist` so that open
rooms aren't listed twice (in the rooms list and the bookmarks list).
[jcbrand]
@ -1136,13 +239,13 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
- #628 Fixes the bug in displaying chat status during private chat. [saganshul]
- #628 Changes the message displayed while typing from a different resource of the same user. [smitbose]
- #675 Time format made configurable.
See [time_format](https://conversejs.org/docs/html/configuration.html#time-format)
See [time_format](https://conversejs.org/docs/html/configurations.html#time-format)
[smitbose]
- #682 Add "Send" button to input box in chat dialog window.
See [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button)
See [show_send_button](https://conversejs.org/docs/html/configurations.html#show-send-button)
[saganshul]
- #704 Automatic fetching of registration form when
[registration_domain](https://conversejs.org/docs/html/configuration.html#registration-domain)
[registration_domain](https://conversejs.org/docs/html/configurations.html#registration-domain)
is set. [smitbose]
- #806 The `_converse.listen` API event listeners aren't triggered. [jcbrand]
- #807 Error: Plugin "converse-dragresize" tried to override HeadlinesBoxView but it's not found. [jcbrand]
@ -1244,7 +347,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
## 2.0.4 (2016-12-13)
- #737: Bugfix. Translations weren't being applied. [jcbrand]
- Fetch room info and store it on the room model.
For context, see: https://xmpp.org/extensions/xep-0045.html#disco-roominfo [jcbrand]
For context, see: http://xmpp.org/extensions/xep-0045.html#disco-roominfo [jcbrand]
- Bugfix. Switching from bookmarks form to config form shows only the spinner. [jcbrand]
- Bugfix. Other room occupants sometimes not shown when reloading the page. [jcbrand]
- Bugfix. Due to changes in `converse-core` the controlbox wasn't aware anymore of

View File

@ -2,11 +2,11 @@
*
* An XMPP chat client that runs in the browser.
*
* Version: 10.1.6
* Version: 3.3.2
*
* Copyright: JC Brand 2013-2018
* Copyright: JC Brand 2012-2017
* 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
* You can download it at: https://github.com/jcbrand/converse.js/releases
*/

2
Gemfile Normal file
View File

@ -0,0 +1,2 @@
source 'https://rubygems.org'
gem 'sass', '~> 3.3'

13
Gemfile.lock Normal file
View File

@ -0,0 +1,13 @@
GEM
remote: https://rubygems.org/
specs:
sass (3.4.14)
PLATFORMS
ruby
DEPENDENCIES
sass (~> 3.3)
BUNDLED WITH
1.10.3

318
Makefile
View File

@ -1,269 +1,231 @@
SHELL := /bin/bash --login
# You can set these variables from the command line.
BOOTSTRAP = ./node_modules/
UGLIFYJS ?= node_modules/.bin/uglifyjs
BABEL ?= node_modules/.bin/babel
BOURBON_TEMPLATES = ./node_modules/bourbon/app/assets/stylesheets/
BUILDDIR = ./docs
KARMA ?= ./node_modules/.bin/karma
CLEANCSS ?= ./node_modules/clean-css-cli/bin/cleancss
BUNDLE ?= ./.bundle/bin/bundle
CHROMIUM ?= ./node_modules/.bin/run-headless-chromium
CLEANCSS ?= ./node_modules/clean-css-cli/bin/cleancss --skip-rebase
ESLINT ?= ./node_modules/.bin/eslint
HTTPSERVE ?= ./node_modules/.bin/http-server
HTTPSERVE_PORT ?= 8000
INKSCAPE ?= inkscape
INSTALL ?= install
JSDOC ?= ./node_modules/.bin/jsdoc
OXIPNG ?= oxipng
PAPER =
PO2JSON ?= ./node_modules/.bin/po2json
RJS ?= ./node_modules/.bin/r.js
NPX ?= ./node_modules/.bin/npx
SASS ?= ./node_modules/.bin/sass
SED ?= sed
SASS ?= ./.bundle/bin/sass
SPHINXBUILD ?= ./bin/sphinx-build
SED ?= sed
SPHINXOPTS =
XGETTEXT = xgettext
# In the case user wishes to use RVM
USE_RVM ?= false
RVM_RUBY_VERSION ?= 2.4.2
ifeq ($(USE_RVM),true)
RVM_USE = rvm use $(RVM_RUBY_VERSION)
endif
# 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
all: dev 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 " all A synonym for 'make dev'."
@echo " build Create minified builds of converse.js and all its dependencies."
@echo " changes Make an overview of all changed/added/deprecated items added to the documentation."
@echo " clean Remove downloaded the stamp-* guard files as well as all NPM and Ruby packages."
@echo " css Generate CSS from the Sass files."
@echo " dev Set up the development environment. To force a fresh start, run 'make clean' first."
@echo " epub Export the documentation to epub."
@echo " html Make standalone HTML files of the documentation."
@echo " doc Same as "doc". Make standalone HTML files of the documentation."
@echo " linkcheck Check all documentation external links for integrity."
@echo " po Generate gettext PO files for each i18n language."
@echo " po2json Generate JSON files from the language PO files."
@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."
@echo " stamp-npm Install NPM dependencies and create the guard file stamp-npm which will prevent those dependencies from being installed again."
@echo " stamp-bundler Install Bundler (Ruby) dependencies and create the guard file stamp-bundler which will prevent those dependencies from being installed again."
@echo " watch Tells Sass to watch the .scss files for changes and then automatically update the CSS files."
########################################################################
## Miscellaneous
.PHONY: serve
serve: node_modules dist
serve: dev
$(HTTPSERVE) -p $(HTTPSERVE_PORT) -c-1
.PHONY: serve_bg
serve_bg: node_modules
serve_bg: dev
$(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
GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.2 -c
.PHONY: pot
pot: src/i18n/converse.pot
pot: dist/converse-no-dependencies.js
$(GETTEXT) 2>&1 > /dev/null; exit $$?;
.PHONY: po
po:
find ./src/i18n -maxdepth 1 -mindepth 1 -type d -exec msgmerge {}/LC_MESSAGES/converse.po ./src/i18n/converse.pot -U \;
find ./locale -maxdepth 1 -mindepth 1 -type d -exec msgmerge {}/LC_MESSAGES/converse.po ./locale/converse.pot -U \;
.PHONY: po2json
po2json:
find ./locale -maxdepth 1 -mindepth 1 -type d -exec $(PO2JSON) -f jed1.x -d converse {}/LC_MESSAGES/converse.po {}/LC_MESSAGES/converse.json \;
########################################################################
## 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
.PHONY: release
release:
$(SED) -ri s/Version:\ [0-9]\+\.[0-9]\+\.[0-9]\+/Version:\ $(VERSION)/ COPYRIGHT
$(SED) -ri s/Version:\ [0-9]\+\.[0-9]\+\.[0-9]\+/Version:\ $(VERSION)/ src/start.frag
$(SED) -ri s/Project-Id-Version:\ Converse\.js\ [0-9]\+\.[0-9]\+\.[0-9]\+/Project-Id-Version:\ Converse.js\ $(VERSION)/ locale/converse.pot
$(SED) -ri s/\"version\":\ \"[0-9]\+\.[0-9]\+\.[0-9]\+\"/\"version\":\ \"$(VERSION)\"/ package.json
$(SED) -ri s/--package-version=[0-9]\+\.[0-9]\+\.[0-9]\+/--package-version=$(VERSION)/ Makefile
$(SED) -ri s/v[0-9]\+\.[0-9]\+\.[0-9]\+\.zip/v$(VERSION)\.zip/ index.html
$(SED) -ri s/v[0-9]\+\.[0-9]\+\.[0-9]\+\.tar\.gz/v$(VERSION)\.tar\.gz/ index.html
$(SED) -ri s/version\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/version\ =\ \'$(VERSION)\'/ docs/source/conf.py
$(SED) -ri s/release\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/release\ =\ \'$(VERSION)\'/ docs/source/conf.py
$(SED) -ri "s/(Unreleased)/`date +%Y-%m-%d`/" CHANGES.md
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
make po2json
make build
########################################################################
## Install dependencies
${NVM_DIR}/nvm.sh:
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
source ~/.bashrc
stamp-npm: package.json
npm install && touch stamp-npm
.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
stamp-bundler: Gemfile
mkdir -p .bundle
$(RVM_USE)
gem install --user bundler --bindir .bundle/bin
$(BUNDLE) install --path .bundle --binstubs .bundle/bin
touch stamp-bundler
.PHONY: clean
clean:
npm run clean
rm -rf lib bin include parts
-rm -f stamp-npm stamp-bundler package-lock.json
-rm -rf node_modules .bundle
.PHONY: dev
dev: node_modules
npm run dev
.PHONY: devserver
devserver: node_modules
npm run serve
dev: stamp-bundler stamp-npm
########################################################################
## Builds
dist/converse-no-dependencies.js: src webpack/webpack.common.js webpack/webpack.nodeps.js @converse/headless node_modules
npm run nodeps
.PHONY: css
css: sass/*.scss css/converse.css css/converse.min.css css/mobile.min.css css/theme.min.css css/converse-muc-embedded.min.css css/inverse.css css/inverse.min.css
dist/converse.js:: node_modules
npm run build
css/inverse.css:: stamp-bundler sass sass/*
$(SASS) -I $(BOURBON_TEMPLATES) sass/inverse/inverse.scss css/inverse.css
dist/converse.css:: node_modules
npm run build
css/inverse.min.css:: css/inverse.css
$(CLEANCSS) css/inverse.css > css/inverse.min.css
dist/website.css:: node_modules src/shared/styles/website.scss
$(SASS) --load-path=$(BOOTSTRAP) src/shared/styles/website.scss $@
css/converse-muc-embedded.css:: stamp-bundler sass/*
$(SASS) -I $(BOURBON_TEMPLATES) sass/_muc_embedded.scss css/converse-muc-embedded.css
dist/website.min.css:: node_modules dist/website.css
$(CLEANCSS) dist/website.css > $@
css/converse-muc-embedded.min.css:: stamp-bundler sass css/converse-muc-embedded.css
$(CLEANCSS) css/converse-muc-embedded.css > css/converse-muc-embedded.min.css
css/converse.css:: stamp-bundler sass/*
$(SASS) -I $(BOURBON_TEMPLATES) sass/converse/converse.scss css/converse.css
css/converse.min.css:: css/converse.css
$(CLEANCSS) css/converse.css > css/converse.min.css
css/theme.min.css:: stamp-npm css/theme.css
$(CLEANCSS) css/theme.css > css/theme.min.css
css/mobile.min.css:: stamp-npm sass/*
$(CLEANCSS) css/mobile.css > css/mobile.min.css
.PHONY: watch
watch: node_modules
npm run watch
watch: stamp-bundler
$(SASS) --watch -I ./node_modules/bourbon/app/assets/stylesheets/ sass/converse/converse.scss:css/converse.css sass/_muc_embedded.scss:css/converse-muc-embedded.css sass/inverse/inverse.scss:css/inverse.css
.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 \
.PHONY: watchjs
watchjs: stamp-npm
$(BABEL) --source-maps --watch=./src --out-dir=./builds
logo/conversejs-transparent%.png:: logo/conversejs-transparent.svg
$(INKSCAPE) -e $@ -w $* $<
$(OXIPNG) $@
transpile: stamp-npm src
$(BABEL) --source-maps --out-dir=./builds ./src
$(BABEL) --source-maps --out-dir=./builds ./node_modules/backbone.vdomview/backbone.vdomview.js
touch transpile
logo/conversejs-filled%.png:: logo/conversejs-filled.svg
$(INKSCAPE) -e $@ -w $* $<
$(OXIPNG) $@
BUILDS = dist/converse.js \
dist/converse.min.js \
dist/converse-headless.js \
dist/converse-headless.min.js \
dist/converse-muc-embedded.js \
dist/converse-muc-embedded.min.js \
dist/converse-no-dependencies.min.js \
dist/converse-no-dependencies.js
@converse/headless: src/headless
# dist/converse-esnext.js \
# dist/converse-esnext.min.js \
src/headless/dist/converse-headless.js: src webpack/webpack.common.js node_modules @converse/headless
npm run headless-dev
dist/converse.js: transpile src node_modules
$(RJS) -o src/build.js include=converse out=dist/converse.js optimize=none
dist/converse.min.js: transpile src node_modules
$(RJS) -o src/build.js include=converse out=dist/converse.min.js
dist/converse-headless.js: transpile src node_modules
$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.js optimize=none
dist/converse-headless.min.js: transpile src node_modules
$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.min.js
dist/converse-esnext.js: src node_modules
$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.js optimize=none
dist/converse-esnext.min.js: src node_modules
$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.min.js
dist/converse-no-dependencies.js: transpile src node_modules
$(RJS) -o src/build-no-dependencies.js optimize=none out=dist/converse-no-dependencies.js
dist/converse-no-dependencies.min.js: transpile src node_modules
$(RJS) -o src/build-no-dependencies.js out=dist/converse-no-dependencies.min.js
dist/converse-muc-embedded.js: transpile src node_modules
$(RJS) -o src/build.js paths.converse=src/converse-embedded include=converse out=dist/converse-muc-embedded.js optimize=none
dist/converse-muc-embedded.min.js: transpile src node_modules
$(RJS) -o src/build.js paths.converse=src/converse-embedded include=converse out=dist/converse-muc-embedded.min.js
src/headless/dist/converse-headless.min.js: src webpack/webpack.common.js node_modules @converse/headless
npm run headless
.PHONY: dist
dist:: build
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
.PHONY: build
build:: dev css transpile $(BUILDS)
########################################################################
## Tests
.PHONY: eslint
eslint: node_modules
npm run lint
eslint: stamp-npm
$(ESLINT) src/
$(ESLINT) spec/
.PHONY: check
check: eslint | dist/converse.js dist/converse.css
npm run test -- $(ARGS)
.PHONY: test
test:
npm run test -- $(ARGS)
check: eslint
LOG_CR_VERBOSITY=INFO $(CHROMIUM) --no-sandbox http://localhost:$(HTTPSERVE_PORT)/tests.html
########################################################################
## 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
html:
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

71
Makefile.win Normal file
View File

@ -0,0 +1,71 @@
# You can set these variables from the command line.
GRUNT ?= node_modules\.bin\grunt.cmd
BOWER ?= node_modules\.bin\bower.cmd
PHANTOMJS ?= node_modules\.bin\phantomjs.cmd
RJS ?= ./node_modules/.bin/r.js.cmd
SASS ?= sass
RMRF ?= rmdir /q /s
RMF ?= del /q
HTTPSERVE ?= ./node_modules/.bin/http-server.cmd
.PHONY: all help clean css minjs build
all: dev
help:
@echo "Please use \`make <target>' where <target> is one of the following"
@echo " dev to set up the development environment"
@echo " build create minified builds containing converse.js and all its dependencies"
@echo " serve to serve this directory via a webserver on port 8000"
########################################################################
## Miscellaneous
serve:
$(HTTPSERVE) -p 8000
########################################################################
## Install dependencies
stamp-npm: package.json
npm install
$(GRUNT) touch:npm
stamp-bower: stamp-npm bower.json
$(BOWER) install
$(GRUNT) touch:bower
clean::
@if EXIST stamp-npm $(RMF) stamp-npm
@if EXIST stamp-bower $(RMF) stamp-bower
@if EXIST node_modules\. $(RMRF) node_modules
@if EXIST components\. $(RMRF) components
dev: clean
npm install
$(BOWER) update
bundler install --path=.
########################################################################
## Builds
css::
$(SASS) sass/converse.scss > css/converse.css
.PHONY: build
build:: stamp-npm
$(GRUNT) jst
$(GRUNT) cssmin
$(RJS) -o src/build.js
$(RJS) -o src/build.js optimize=none out=dist/converse.js
$(RJS) -o src/build-no-jquery.js
$(RJS) -o src/build-no-jquery.js optimize=none out=dist/converse.nojquery.js
$(RJS) -o src/build-no-dependencies.js
$(RJS) -o src/build-no-dependencies.js optimize=none out=dist/converse-no-dependencies.js
########################################################################
## Tests
check:: stamp-npm
$(PHANTOMJS) node_modules/phantom-jasmine/lib/run_jasmine_test.coffee tests.html

View File

@ -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?}/
```

212
README.md
View File

@ -1,32 +1,37 @@
<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>
# converse.js
[![Greenkeeper badge](https://badges.greenkeeper.io/jcbrand/converse.js.svg)](https://greenkeeper.io/)
[![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)
[![Travis](https://api.travis-ci.org/jcbrand/converse.js.png?branch=master)](https://travis-ci.org/jcbrand/converse.js)
[![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.
[Converse.js](https://conversejs.org) is a web based [XMPP/Jabber](http://xmpp.org) instant messaging 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.
It enables you to add chat functionality to your website, independent of
any specific backend. You will however need an XMPP server to connect
to, either your own, or a public one.
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).
Converse.js 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).
### Converse.js: As seen on the conversejs.org website
![Screenshot of Converse.js](https://opkode.com/img/converse-screenshot.png)
### inVerse: a fullscreen version of converse.js
Converse.js is also available in a fullscreen version, called [inVerse](https://inverse.chat)
![Screenshot of inVerse](https://opkode.com/img/inverse-screenshot.png)
## Documentation
The developer/integrator documentation can be found at [https://conversejs.org/docs/html](https://conversejs.org/docs/html).
@ -34,155 +39,86 @@ The developer/integrator documentation can be found at [https://conversejs.org/d
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.
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://jcbrand.github.io/pluggable.js/)
- Single-user chat
- Contacts and groups
- Multi-user chat rooms [XEP 45](http://xmpp.org/extensions/xep-0045.html)
- Direct invitations to chat rooms [XEP 249](http://xmpp.org/extensions/xep-0249.html)
- vCard support [XEP 54](http://xmpp.org/extensions/xep-0054.html)
- Service discovery [XEP 30](http://xmpp.org/extensions/xep-0030.html)
- In-band registration [XEP 77](http://xmpp.org/extensions/xep-0077.html)
- Chat room bookmarks [XEP 48](http://xmpp.org/extensions/xep-0048.html)
- Roster item exchange [XEP 144](http://xmpp.org/extensions/tmp/xep-0144-1.1.html)
- Chat statuses (online, busy, away, offline)
- 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
- Typing and state notifications [XEP 85](http://xmpp.org/extensions/xep-0085.html)
- Messages appear in all connnected chat clients [XEP 280](http://xmpp.org/extensions/xep-0280.html)
- Third person "/me" messages [XEP 245](http://xmpp.org/extensions/xep-0245.html)
- XMPP Ping [XEP 199](http://xmpp.org/extensions/xep-0199.html)
- Server-side archiving of messages [XEP 313](http://xmpp.org/extensions/xep-0313.html)
- Client state indication [XEP 352](http://xmpp.org/extensions/xep-0352.html)
- Off-the-record encryption
- Translated into 16 languages
### Supported XMPP Extensions
## Integration into other frameworks
- [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)
- **[Ruby on Rails](http://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
- **[Django](http://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
- **[Plone](http://plone.com)**: [collective.xmpp.chat](http://github.com/collective/collective.xmpp.chat)
- **[Roundcube](http://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
- **[Wordpress](http://wordpress.org)**: [ConverseJS](http://wordpress.org/plugins/conversejs)
- **[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/)
- **[Alfresco](http://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)
- **[Friendica](http://friendica.com)**: [converse](https://github.com/friendica/friendica-addons/tree/master/xmpp/converse)
- **[Tiki Wiki CMS Groupware](http://tiki.org)**: [built-in optional feature](https://doc.tiki.org/XMPP)
## Screencasts
*Note: These screencasts are already quite old! Converse.js has grown and evolved further since then.*
- [In a static HTML page](http://opkode.com/media/blog/2013/04/02/converse.js-xmpp-instant-messaging-with-javascript).
Here we chat to external XMPP accounts on Jabber.org and Gmail.
- [Integrated into a Plone site](http://opkode.com/media/blog/instant-messaging-for-plone-with-javascript-and-xmpp)
via collective.xmpp.chat.
- [Off-the-record encryption](https://opkode.com/media/blog/2013/11/11/conversejs-otr-support)
in Converse 0.7.
## Tests
We use behavior-driven tests written with [jasmine.js](https://jasmine.github.io/).
Run `make check` to execute all the tests.
Open [tests.html](https://github.com/jcbrand/converse.js/blob/master/tests.html) in your browser, and the tests will run automatically.
## 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).
For support queries and discussions, please join the mailing list: <conversejs@librelist.com>
Also take a look at the [mailing list archives](http://librelist.com/browser/conversejs).
Issues can be logged on the [Github issue tracker](https://github.com/jcbrand/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).
Recently we have started accepting donations via [Patreon](https://www.patreon.com/jcbrand) and [Liberapay](https://liberapay.com/jcbrand).
## Sponsors
The following people are making recurring donations:
<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>
* [Rafael](https://www.patreon.com/user/creators?u=4340078)
* [mt7479](https://www.patreon.com/user/creators?u=3892290)
* [roelra](https://www.patreon.com/user/creators?u=5958918)
* An anonymous backer on Liberapay
Additionally this project is supported by
* [![KeyCDN](https://conversejs.org/logo/keycdn.png)](https://www.keycdn.com/)
* [![Wikisuite](https://conversejs.org/logo/wikisuite.png)](http://wikisuite.org)

View File

@ -1,18 +1,18 @@
# 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`
1. Run `make check` to check that all tests pass.
2. Decide on a version number, e.g. 2.0.5
3. Run `make release VERSION=2.0.5`
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`
6. `git commit -am "New release 2.0.5"`
7. `git tag -s v2.0.5
8. Run `git push && git push --tags`
9. Update http://conversejs.org
10. Create `2.0.5` directory for the CDN.
* Create a new version for the CDN by copying
* Check out the correct tag
* Update `index.html` to point to that version of the CDN
* Run `make dist`
* Do the same for the root dir
11. Run `npm publish`

View File

@ -1,10 +0,0 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": [">1%", "not ie 11", "not op_mini all", "not dead"]
}
}]
],
"plugins": []
}

210
bootstrap.py Normal file
View File

@ -0,0 +1,210 @@
##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os
import shutil
import sys
import tempfile
from optparse import OptionParser
__version__ = '2015-07-01'
# See zc.buildout's changelog if this version is up to date.
tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
usage = '''\
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
Bootstraps a buildout-based project.
Simply run this script in a directory containing a buildout.cfg, using the
Python that you want bin/buildout to use.
Note that by using --find-links to point to local resources, you can keep
this script from going over the network.
'''
parser = OptionParser(usage=usage)
parser.add_option("--version",
action="store_true", default=False,
help=("Return bootstrap.py version."))
parser.add_option("-t", "--accept-buildout-test-releases",
dest='accept_buildout_test_releases',
action="store_true", default=False,
help=("Normally, if you do not specify a --version, the "
"bootstrap script and buildout gets the newest "
"*final* versions of zc.buildout and its recipes and "
"extensions for you. If you use this flag, "
"bootstrap and buildout will get the newest releases "
"even if they are alphas or betas."))
parser.add_option("-c", "--config-file",
help=("Specify the path to the buildout configuration "
"file to be used."))
parser.add_option("-f", "--find-links",
help=("Specify a URL to search for buildout releases"))
parser.add_option("--allow-site-packages",
action="store_true", default=False,
help=("Let bootstrap.py use existing site packages"))
parser.add_option("--buildout-version",
help="Use a specific zc.buildout version")
parser.add_option("--setuptools-version",
help="Use a specific setuptools version")
parser.add_option("--setuptools-to-dir",
help=("Allow for re-use of existing directory of "
"setuptools versions"))
options, args = parser.parse_args()
if options.version:
print("bootstrap.py version %s" % __version__)
sys.exit(0)
######################################################################
# load/install setuptools
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
ez = {}
if os.path.exists('ez_setup.py'):
exec(open('ez_setup.py').read(), ez)
else:
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
if not options.allow_site_packages:
# ez_setup imports site, which adds site packages
# this will remove them from the path to ensure that incompatible versions
# of setuptools are not in the path
import site
# inside a virtualenv, there is no 'getsitepackages'.
# We can't remove these reliably
if hasattr(site, 'getsitepackages'):
for sitepackage_path in site.getsitepackages():
# Strip all site-packages directories from sys.path that
# are not sys.prefix; this is because on Windows
# sys.prefix is a site-package directory.
if sitepackage_path != sys.prefix:
sys.path[:] = [x for x in sys.path
if sitepackage_path not in x]
setup_args = dict(to_dir=tmpeggs, download_delay=0)
if options.setuptools_version is not None:
setup_args['version'] = options.setuptools_version
if options.setuptools_to_dir is not None:
setup_args['to_dir'] = options.setuptools_to_dir
ez['use_setuptools'](**setup_args)
import setuptools
import pkg_resources
# This does not (always?) update the default working set. We will
# do it.
for path in sys.path:
if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path)
######################################################################
# Install buildout
ws = pkg_resources.working_set
setuptools_path = ws.find(
pkg_resources.Requirement.parse('setuptools')).location
# Fix sys.path here as easy_install.pth added before PYTHONPATH
cmd = [sys.executable, '-c',
'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
'from setuptools.command.easy_install import main; main()',
'-mZqNxd', tmpeggs]
find_links = os.environ.get(
'bootstrap-testing-find-links',
options.find_links or
('http://downloads.buildout.org/'
if options.accept_buildout_test_releases else None)
)
if find_links:
cmd.extend(['-f', find_links])
requirement = 'zc.buildout'
version = options.buildout_version
if version is None and not options.accept_buildout_test_releases:
# Figure out the most recent final version of zc.buildout.
import setuptools.package_index
_final_parts = '*final-', '*final'
def _final_version(parsed_version):
try:
return not parsed_version.is_prerelease
except AttributeError:
# Older setuptools
for part in parsed_version:
if (part[:1] == '*') and (part not in _final_parts):
return False
return True
index = setuptools.package_index.PackageIndex(
search_path=[setuptools_path])
if find_links:
index.add_find_links((find_links,))
req = pkg_resources.Requirement.parse(requirement)
if index.obtain(req) is not None:
best = []
bestv = None
for dist in index[req.project_name]:
distv = dist.parsed_version
if _final_version(distv):
if bestv is None or distv > bestv:
best = [dist]
bestv = distv
elif distv == bestv:
best.append(dist)
if best:
best.sort()
version = best[-1].version
if version:
requirement = '=='.join((requirement, version))
cmd.append(requirement)
import subprocess
if subprocess.call(cmd) != 0:
raise Exception(
"Failed to execute command:\n%s" % repr(cmd)[1:-1])
######################################################################
# Import and run buildout
ws.add_entry(tmpeggs)
ws.require(requirement)
import zc.buildout.buildout
if not [a for a in args if '=' not in a]:
args.append('bootstrap')
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args[0:0] = ['-c', options.config_file]
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)

22
buildout.cfg Normal file
View File

@ -0,0 +1,22 @@
[buildout]
parts =
sphinx
versions = versions
[sphinx]
recipe = zc.recipe.egg
eggs =
Sphinx
sphinx-bootstrap-theme
[versions]
docutils = 0.13.1
Jinja2 = 2.9.5
MarkupSafe = 0.23
Pygments = 2.2.0
six = 1.10.0
setuptools = 28.6.1
Sphinx = 1.5.2
z3c.recipe.egg = 2.0.3
zc.buildout = 2.5.3

3
builds/README.rst Normal file
View File

@ -0,0 +1,3 @@
This directory exists as a location for intermediate files generated by the
Babel compiler, before they're bundled into distribution bundles in the
`./dist/` directory.

View File

@ -4,7 +4,7 @@
"type": "library",
"license": "MPL-2.0",
"minimum-stability": "stable",
"homepage": "https://conversejs.org/",
"homepage": "http://conversejs.org/",
"keywords": ["xmpp", "messaging", "chat", "presence"],
"require": {}
}

23
converse-logs/README.md Normal file
View File

@ -0,0 +1,23 @@
# How to use saved Chrome/Chromium logs to replay events
**NOTE**: This feature is very experimental and in many cases doesn't work
without data massaging and ugly hacks.
It's possible to save the log output from Chrome/Chromium (I haven't tried this
yet with any other browser) and then to replay that log output in the browser.
This can be a very helpful technique to track down bugs.
To do this, follow the following steps:
1. Save the log file (right click and then click "Save as" in the browser's console).
2. Rename the log file, making sure it ends in `.html`
3. Move the log file to the `converse-logs` directory in the converse.js repo.
4. Add `<log>` to the top of the log file and `</log>` to the bottom of the log file.
5. In `converse-logs/converse-logs.js`, add a new entry for the log file (don't
include the `.html` part of the file name.
6. Make sure that `spec/transcripts` is "required"-ed in `tests/main.js`
6. Open `tests.html` in your browser.
Your logs will run first, and then all the other tests will run afterwards.

View File

@ -0,0 +1,5 @@
define("transcripts", [
"tpl!../../converse-logs/missing_messages",
], function () {
return arguments;
});

View File

@ -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>

6
css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,66 @@
/*
Color scheme helpers:
https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
*/
#converse-embedded-chat {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
bottom: auto;
right: auto;
position: relative;
width: 100%; }
#converse-embedded-chat *, #converse-embedded-chat *:before, #converse-embedded-chat *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
#converse-embedded-chat form.pure-form.converse-centered-form {
position: absolute;
top: 30%;
transform: translateY(-50%); }
#converse-embedded-chat .chatroom {
width: auto; }
#converse-embedded-chat .flyout {
bottom: auto;
display: block;
position: relative; }
#converse-embedded-chat .chatbox {
float: none; }
#converse-embedded-chat .chatbox .box-flyout {
box-shadow: none; }
#converse-embedded-chat .chatbox .chat-title {
padding: 0.3em;
font-size: 120%; }
#converse-embedded-chat .chatbox-btn {
display: none; }
#converse-embedded-chat .chatroom .box-flyout {
min-width: auto;
width: 100%;
height: 55vh; }
#converse-embedded-chat .chatroom .box-flyout .chat-body {
height: -webkit-calc(100% - 55px);
height: calc(100% - 55px); }
#converse-embedded-chat .chatroom .box-flyout .occupants-heading {
font-size: 120%; }
#converse-embedded-chat .chatroom .box-flyout .chat-content {
height: calc(100% - 97px); }
#converse-embedded-chat .chatroom .box-flyout .chat-content .chat-message {
margin: 0.5em;
font-size: 120%; }
#converse-embedded-chat .chatroom .box-flyout .sendXMPPMessage .chat-textarea {
padding: 0.5em;
font-size: 110%; }
#converse-embedded-chat .chatroom .box-flyout .chatroom-body .chatroom-form-container {
font-size: 180%;
float: left;
height: 100%;
position: relative; }
#converse-embedded-chat .chatroom .box-flyout .chatroom-body .chatroom-form-container input {
font-size: 60%; }
#converse-embedded-chat .chatroom .box-flyout .occupants .occupant-list {
padding-left: 0.3em; }
#converse-embedded-chat .chatroom .box-flyout .occupants .occupant-list li.occupant {
font-size: 120%; }
/*# sourceMappingURL=converse-muc-embedded.css.map */

2921
css/converse.css Normal file

File diff suppressed because it is too large Load Diff

4
css/font-awesome.min.css vendored Normal file

File diff suppressed because one or more lines are too long

4
css/images/arrow.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="12px" viewBox="0 0 24 12" zoomAndPan="disable">
<line x1="0" y1="0" x2="12" y2="12" style="stroke:#ccc;stroke-width:1.5" />
<line x1="24" y1="0" x2="12" y2="12" style="stroke:#ccc;stroke-width:1.5" />
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

Before

Width:  |  Height:  |  Size: 1009 B

After

Width:  |  Height:  |  Size: 1009 B

View File

Before

Width:  |  Height:  |  Size: 1015 B

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="12px" viewBox="0 0 24 12" zoomAndPan="disable">
<line x1="0" y1="0" x2="12" y2="12" style="stroke:rgba(255,255,255,0.65);stroke-width:1" />
<line x1="24" y1="0" x2="12" y2="12" style="stroke:rgba(255,255,255,0.65);stroke-width:1" />
</svg>

After

Width:  |  Height:  |  Size: 348 B

BIN
css/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

BIN
css/images/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

3091
css/inverse.css Normal file

File diff suppressed because it is too large Load Diff

82
css/jasmine.css Normal file
View File

@ -0,0 +1,82 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: goldenrod; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: lightgreen; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: lightgreen; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: goldenrod; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: lightgreen; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: goldenrod; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: goldenrod; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }

13
css/mobile.css Normal file
View File

@ -0,0 +1,13 @@
#conversejs {
left: 0px;
right: 0px;
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
.converse-chatroom {
font-size: 14px;
}
.intro {
padding: 0;
height: 100vh;
}

365
css/theme.css Normal file
View File

@ -0,0 +1,365 @@
body {
width: 100%;
height: 100%;
font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #ffffff;
background-color: #211018;
}
html {
width: 100%;
height: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0 0 35px;
font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: 700;
letter-spacing: 1px;
}
p {
margin: 0 0 25px;
font-size: 18px;
line-height: 1.5;
}
@media (min-width: 767px) {
p {
margin: 0 0 35px;
font-size: 20px;
line-height: 1.6;
}
}
a {
color: #82B397;
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
a:hover,
a:focus {
text-decoration: none;
color: #00aaff;
}
.light {
font-weight: 400;
}
.navbar {
margin-bottom: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
text-transform: uppercase;
font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
background-color: #211018;
}
.navbar-brand {
font-weight: 700;
}
.navbar-brand:focus {
outline: none;
}
.navbar-custom a {
color: #ffffff;
}
.navbar-custom .nav li a {
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background 0.3s ease-in-out;
}
.navbar-custom .nav li a:hover,
.navbar-custom .nav li a:focus,
.navbar-custom .nav li.active {
outline: none;
background-color: rgba(255, 255, 255, 0.2);
}
.navbar-toggle {
padding: 4px 6px;
font-size: 16px;
color: #ffffff;
}
.navbar-toggle:focus,
.navbar-toggle:active {
outline: none;
}
@media (min-width: 767px) {
.navbar {
padding: 20px 0;
border-bottom: none;
letter-spacing: 1px;
background: transparent;
-webkit-transition: background 0.5s ease-in-out, padding 0.5s ease-in-out;
-moz-transition: background 0.5s ease-in-out, padding 0.5s ease-in-out;
transition: background 0.5s ease-in-out, padding 0.5s ease-in-out;
}
.top-nav-collapse {
padding: 0;
background-color: #211018;
}
.navbar-custom.top-nav-collapse {
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
}
@media (max-width: 480px) {
.navbar {
display: none;
}
}
.features-section,
.outro,
.intro {
width: 100%;
padding: 100px 0;
text-align: center;
color: #fff;
}
.intro {
background: url(images/header.jpg) no-repeat bottom center scroll;
background-color: #211018;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
-o-background-size: cover;
}
.features-section {
background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #85505f, #384955, #655361);
}
.features-section a {
color: #82B397;
}
.outro {
background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #384955, #655361, #85505f);
}
.brand-heading {
font-size: 2em;
text-align: center;
margin-top: 3em;
}
.brand-heading-embedded {
margin-top: 1.5em;
}
.intro-text {
font-size: 18px;
}
@media (min-width: 767px) {
.intro {
height: 100%;
padding: 0;
}
.brand-heading {
font-size: 80px;
}
.intro-text {
font-size: 25px;
}
}
.btn-circle {
width: 70px;
height: 70px;
margin-top: 15px;
padding: 7px 16px;
border: 2px solid #ffffff;
border-radius: 35px;
font-size: 40px;
color: #ffffff;
background: transparent;
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background 0.3s ease-in-out;
}
.btn-circle:hover,
.btn-circle:focus {
outline: none;
color: #ffffff;
background: rgba(255, 255, 255, 0.1);
}
.page-scroll .btn-circle i.animated {
-webkit-transition-property: -webkit-transform;
-webkit-transition-duration: 1s;
-moz-transition-property: -moz-transform;
-moz-transition-duration: 1s;
}
.page-scroll .btn-circle:hover i.animated {
-webkit-animation-name: pulse;
-moz-animation-name: pulse;
-webkit-animation-duration: 1.5s;
-moz-animation-duration: 1.5s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
}
/*
@-webkit-keyframes pulse {
0 {
-webkit-transform: scale(1);
transform: scale(1);
}
50% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@-moz-keyframes pulse {
0 {
-moz-transform: scale(1);
transform: scale(1);
}
50% {
-moz-transform: scale(1.2);
transform: scale(1.2);
}
100% {
-moz-transform: scale(1);
transform: scale(1);
}
}
*/
.content-section {
padding-top: 100px;
}
.donate-section {
width: 100%;
padding: 50px 0;
color: #ffffff;
background-color: #211018;
}
.donate-section p.bitcoin-header {
margin: 0 0 5px;
}
@media (min-width: 767px) {
.content-section {
padding-top: 150px;
padding-bottom: 50px;
}
.donate-section {
padding: 100px 0;
}
}
.btn {
text-transform: uppercase;
font-family: FontAwesome;
font-weight: 400;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.btn-default {
border: 1px solid #82B397;
color: #82B397;
background-color: transparent;
}
.btn-default:hover,
.btn-default:focus {
border: 1px solid #82B397;
outline: none;
color: #211018;
background-color: #82B397;
}
.btn-huge {
padding: 25px;
font-size: 26px;
}
.banner-social-buttons {
padding-top: 7em;
}
::-moz-selection {
text-shadow: none;
background: #fcfcfc;
background: rgba(255, 255, 255, 0.2);
}
::selection {
text-shadow: none;
background: #fcfcfc;
background: rgba(255, 255, 255, 0.2);
}
img::selection {
background: transparent;
}
img::-moz-selection {
background: transparent;
}
body {
webkit-tap-highlight-color: rgba(255, 255, 255, 0.2);
}
ul.contact,
ul.integration,
ul.screencasts,
ul.features {
text-align: left;
font-size: 19px;
}
.feature-icon {
display: inline-block;
position: relative;
padding-bottom: 5em;
margin-bottom: 2.75em;
cursor: default;
color: #fff;
}
.feature-icon .fa {
display: inline-block;
width: 2em;
height: 2em;
font-size: 4em;
border-radius: 100%;
box-shadow: inset 0 0 0 1px white;
color: white;
line-height: 2.1em;
}
.feature-icon:before {
content: '';
background: white;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -0.325em;
width: 0.65em;
height: 0.65em;
display: block;
border-radius: 100%;
}
.feature-icon:after {
content: '';
position: absolute;
left: 50%;
bottom: 0.65em;
width: 1px;
height: 4.35em;
background: white;
margin-left: -0.5px;
}
.row {
margin-left: 0;
margin-right: 0;
}
.mastodon {
width: 5em;
height: 5em;
}
.sponsors {
clear: both;
font-size: 1.4em;
padding: 2em 0 6em 0;
}
.sponsors h2 {
text-align: center;
}
.sponsors ul {
margin: 0 0 1em 0;
}
.sponsors ul li {
margin: 1em 0;
list-style: none;
}
.sponsors-text {
text-align: left;
padding: 0 0 2em 0;
}

View File

@ -1,103 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Converse - Anonymous login demo</title>
<title>Converse.js</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="description" content="Converse.js: A free chat client for your website" />
<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" />
<meta name="keywords" content="xmpp chat webchat converse.js" />
<link rel="shortcut icon" type="image/ico" href="../css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="node_modules/font-awesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/theme.min.css" />
<script type="text/javascript" src="../analytics.js"></script>
<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>
<![if gte IE 9]>
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/3.2.1/css/converse.min.css" />
<script src="https://cdn.conversejs.org/3.2.1/dist/converse.min.js"></script>
<![endif]>
</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>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom">
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<i class="fa fa-bars"></i>
</button>
</div>
<div class="collapse navbar-collapse navbar-right navbar-main-collapse">
<ul class="nav navbar-nav"><li> <a href="/docs/html/index.html">Documentation</a> </li>
</ul>
</div>
</div>
</nav>
<section id="intro" class="intro" class="container">
<section class="intro">
<div class="intro-body">
<div 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>
<div class="col-md-8 col-md-offset-2">
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse.js</h1>
<p class="intro-text">Anonymous login demo</p>
</div>
</div>
</section>
</div>
</div>
</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

2
demo/config.js Normal file
View File

@ -0,0 +1,2 @@
config.baseUrl = '..';
require.config(config);

View File

@ -1,103 +1,97 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Converse - Anonymous login demo</title>
<title>Converse.js</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="description" content="Converse.js: A free chat client for your website" />
<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>
<meta name="keywords" content="xmpp chat webchat converse.js" />
<link rel="shortcut icon" type="image/ico" href="../css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/font-awesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/theme.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse-muc-embedded.min.css" />
<script type="text/javascript" src="../analytics.js"></script>
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
<![if gte IE 9]>
<script src="../dist/converse-muc-embedded.min.js"></script>
<![endif]>
</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>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom">
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<i class="fa fa-bars"></i>
</button>
</div>
<div class="collapse navbar-collapse navbar-right navbar-main-collapse">
<ul class="nav navbar-nav"><li> <a href="/docs/html/index.html">Documentation</a> </li>
</ul>
</div>
</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>
<div class="col-md-8 col-md-offset-2">
<h1 class="brand-heading brand-heading-embedded"><a style="color: white;" href="/"><i class="icon-conversejs"></i>Converse.js</a></h1>
<p class="intro-text">Embedded MUC chat demo</p>
<div class="converse-container">
<converse-root></converse-root>
<div id="converse-embedded-chat"></div>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
</body>
<script>
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.
auto_reconnect: true,
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).
// Whitelist non-core plugins that we need
whitelisted_plugins: ['converse-muc-embedded'],
// Blacklist plugins which aren't included in the build file,
// so that other code cannot register their own plugins under
// those names.
blacklisted_plugins: [
"converse-bookmarks",
"converse-controlbox",
"converse-dragresize",
"converse-headline",
"converse-minimize",
"converse-otr",
"converse-register",
"converse-vcard",
],
notify_all_room_messages: [
'anonymous@conference.nomnom.im',
],
singleton: true,
locales_url: "../locale/{{{locale}}}/LC_MESSAGES/converse.json",
view_mode: 'embedded',
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,
strict_plugin_dependencies: false
});
</script>
</html>

View File

@ -1,113 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Converse Demos</title>
<title>Converse.js</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="description" content="Converse.js: A free chat client for your website" />
<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>
<meta name="keywords" content="xmpp chat webchat converse.js" />
<link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="/node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="/node_modules/font-awesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="/css/theme.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="/css/converse.min.css" />
<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>
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
<![if gte IE 9]>
<script src="/dist/converse.min.js"></script>
<![endif]>
</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>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom">
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<i class="fa fa-bars"></i>
</button>
<a class="navbar-brand" href="/#page-top">
<i class="fa fa-play-circle"></i> <span class="light">Home</span>
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse navbar-right navbar-main-collapse">
<ul class="nav navbar-nav">
<!-- Hidden li included to remove active class from about link when scrolled up past about section -->
<li class="hidden">
<a href="#page-top"></a>
</li>
<li class="page-scroll">
<a href="#about">About</a>
</li>
<li class="page-scroll">
<a href="#features">Features</a>
</li>
<li class="page-scroll">
<a href="#contact">Contact</a>
</li>
<li>
<a href="/docs/html/manual.html">User Manual</a>
</li>
<li>
<a href="/docs/html/index.html">Documentation</a>
</li>
<li>
<a href="https://github.com/jcbrand/converse.js/releases" class="button" target="_blank">Download</a>
</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
<section id="intro" class="intro" class="container">
<section 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>
<h1 class="brand-heading"><i class="icon-conversejs"></i> Converse.js</h1>
<div class="col-md-8 col-md-offset-2">
<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="https://inverse.chat" target="_blank" rel="noopener">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>
<li><a href="/demo/without_bundled_dependencies.html">Dependencies loaded externally as &lt;script&gt; tags</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
require(['converse'], function (converse) {
(function () {
/* XXX: This function initializes jquery.easing for the https://conversejs.org
* website. This code is only useful in the context of the converse.js
* website and converse.js itself is NOT dependent on it.
*/
var $ = converse.env.jQuery;
$.extend( $.easing, {
easeInOutExpo: function (x, t, b, c, d) {
if (t==0) return b;
if (t==d) return b+c;
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
});
$(window).scroll(function() {
if ($(".navbar").offset().top > 50) {
$(".navbar-fixed-top").addClass("top-nav-collapse");
} else {
$(".navbar-fixed-top").removeClass("top-nav-collapse");
}
});
//jQuery for page scrolling feature - requires jQuery Easing plugin
$('.page-scroll a').bind('click', function(event) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 700, 'easeInOutExpo');
event.preventDefault();
});
})();
converse.initialize({
// Please use this connection manager only for testing purposes
bosh_service_url: 'https://conversejs.org/http-bind/'
bosh_service_url: 'https://conversejs.org/http-bind/',
keepalive: true,
message_carbons: true,
play_sounds: true,
roster_groups: true,
show_controlbox_by_default: true,
});
});
</script>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<title>Converse.js (Non-AMD Example)</title>
<meta charset='utf-8' />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Converse.js: A free chat client for your website" />
<meta name="author" content="JC Brand" />
<link rel="shortcut icon" type="image/ico" href="../css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/font-awesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="../css/theme.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="../css/converse.min.css" />
<!-- BEGIN OTR: Off-the-record encryption stuff. Can be omitted if OTR is not used. -->
<script type="text/javascript" src="../node_modules/otr/build/dep/crypto.js"></script>
<script type="text/javascript" src="../node_modules/otr/build/dep/salsa20.js"></script>
<script type="text/javascript" src="../node_modules/otr/build/dep/bigint.js"></script>
<script type="text/javascript" src="../node_modules/otr/build/dep/eventemitter.js"></script>
<script type="text/javascript" src="../node_modules/otr/build/otr.js"></script>
<!-- END OTR -->
<!-- BEGIN STROPHE -->
<script type="text/javascript" src="../node_modules/strophe.js/strophe.js"></script>
<script type="text/javascript" src="../node_modules/strophejs-plugin-vcard/strophe.vcard.js"></script>
<script type="text/javascript" src="../node_modules/strophejs-plugin-disco/strophe.disco.js"></script>
<script type="text/javascript" src="../node_modules/strophejs-plugin-rsm/strophe.rsm.js"></script>
<script type="text/javascript" src="../node_modules/strophejs-plugin-ping/strophe.ping.js"></script>
<!-- END STROPHE -->
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-attributes.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-class.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-dataset.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-eventlisteners.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-props.js"></script>
<script type="text/javascript" src="../node_modules/snabbdom/dist/snabbdom-style.js"></script>
<!-- BEGIN BACKBONE -->
<script type="text/javascript" src="../node_modules/lodash/lodash.js"></script>
<script type="text/javascript" src="../node_modules/backbone/backbone.js"></script>
<script type="text/javascript" src="../node_modules/backbone.nativeview/backbone.nativeview.js"></script>
<script type="text/javascript" src="../node_modules/backbone.browserStorage/backbone.browserStorage.js"></script>
<script type="text/javascript" src="../node_modules/backbone.overview/dist/backbone.overview.js"></script>
<script type="text/javascript" src="../node_modules/backbone.overview/dist/backbone.orderedlistview.js"></script>
<script type="text/javascript" src="../node_modules/backbone.vdomview/dist/backbone.vdomview.js"></script>
<!-- END BACKBONE -->
<script type="text/javascript" src="../node_modules/awesomplete-avoid-xss/awesomplete.js"></script>
<script type="text/javascript" src="../node_modules/moment/min/moment-with-locales.js"></script>
<script type="text/javascript" src="../3rdparty/lodash.fp.js"></script>
<script src="../dist/converse-no-dependencies.js"></script>
</head>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom">
<section class="intro">
<div class="intro-body">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse.js</h1>
<p class="intro-text">An example page where external dependencies are loaded seperately and not within the converse.js bundle.</p>
<p class="intro-text">Look at the page source for details.</p>
<p class="intro-text">For this page to work, you'll need to
<a href="https://conversejs.org/docs/html/developer_guidelines.html#installing-the-development-and-front-end-dependencies">
install the 3rd party dependencies</a> of converse.js.
</p>
<div class="page-scroll">
</div>
</div>
</div>
</div>
</div>
</section>
</body>
<script>
converse.initialize({
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
prebind: false,
show_controlbox_by_default: true,
debug: true,
roster_groups: true,
keepalive: true
});
</script>
</html>

View File

@ -1,50 +1,79 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Converse</title>
<title>Converse.js</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="description" content="Converse.js: A free chat client for your website" />
<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>
<link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="node_modules/font-awesome/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<script src="node_modules/requirejs/require.js"></script>
<script src="src/config.js"></script>
</head>
<body class="reset" style="background-color: var(--global-background-color)">
<div id="conversejs-bg"></div>
<body id="page-top" data-spy="scroll" data-target=".navbar-custom">
<nav class="navbar navbar-custom navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<i class="fa fa-bars"></i>
</button>
</div>
<div class="collapse navbar-collapse navbar-right navbar-main-collapse">
<ul class="nav navbar-nav"><li> <a href="/docs/html/index.html">Documentation</a> </li>
</ul>
</div>
</div>
</nav>
<section class="intro">
<div class="intro-body">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="brand-heading"><i class="icon-conversejs"></i>converse</h1>
<p class="intro-text">Developer page.</p>
<p class="intro-text">
Converse.js will only work on this page if you have
<a href="https://conversejs.org/docs/html/development.html">set up the development environment</a>.
</p>
</div>
</div>
</div>
</div>
</section>
</body>
<script>
converse.plugins.add('converse-debug', {
initialize () {
const { _converse } = this;
window._converse = _converse;
}
});
require(['converse'], function (converse) {
converse.initialize({
i18n: 'af',
theme: 'dracula',
auto_away: 300,
enable_smacks: true,
loglevel: 'debug',
reuse_scram_keys: true,
prune_messages_above: 100,
i18n: 'en',
// auto_join_rooms: [
// 'discuss@conference.conversejs.org',
// 'prosody@conference.prosody.im',
// 'jdev@conference.jabber.org'
// ],
hide_open_bookmarks: true,
notify_all_room_messages: [
'discuss@conference.conversejs.org'
],
auto_reconnect: true,
// bosh_service_url: 'http://chat.example.org:5280/http-bind/',
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
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' }
show_controlbox_by_default: true,
strict_plugin_dependencies: false,
chatstate_notification_blacklist: ['mulles@movim.eu'],
xhr_user_search: false,
debug: true
});
});
</script>
</body>
</html>

25847
dist/converse-no-dependencies.js vendored Normal file

File diff suppressed because one or more lines are too long

66587
dist/converse.js vendored Normal file

File diff suppressed because one or more lines are too long

1
docs/.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
CHANGES.rst merge=union

59
docs/DEVELOPER.rst Normal file
View File

@ -0,0 +1,59 @@
Subscription flow
=================
Happy flow
----------
Contact1 makes a presence subscription request to contact2.
::
<presence type="subscribe" to="contact2@localhost"/>
Contact1 receives a roster update
::
<iq type="set" to="contact1@localhost">
<query xmlns="jabber:iq:roster">
<item jid="contact2@localhost" ask="subscribe" subscription="none"></item>
</query>
</iq>
Contact2 receives the presence subscription, but no
roster update. We create a roster item manually in
handleIncomingSubscription and add the 'requesting'
property to indicate that this is an incoming request.
Contact2 clicks "Accept". This confirms the
subscription and subscribes back.
::
<presence type="subscribed" to="contact1@localhost"/>
<presence type="subscribe" to="contact1@localhost"/>
IF Contact1 is still online and likewise subscribes back, Contact2 will receive a roster update
::
<iq type="set" to="contact2@localhost">
<query xmlns="jabber:iq:roster">
<item jid="contact1@localhost" ask="subscribe" subscription="from"></item>
</query>
</iq>
ELSE, Contact 2 will receive a roster update (but not an IQ stanza)
::
ask = null
subscription = "from"
Contact1's converse.js client will automatically
approve.
Contact2 receives a roster update (as does contact1).
::
<iq type="set" to="contact2@localhost">
<query xmlns="jabber:iq:roster">
<item jid="contact1@localhost" subscription="both"></item>
</query>
</iq>

View File

@ -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.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@ -35,46 +35,11 @@ h5 {
.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;
max-height: 70vh;
overflow-y: scroll;
}
.bs-sidenav .nav .nav > li > a {

View File

@ -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>

View File

@ -2,12 +2,17 @@
{% extends "!layout.html" %}
{# Custom CSS overrides #}
{% set css_files = css_files + ['_static/style.css'] %}
{% set script_files = script_files + ["../../analytics.js"] %}
{% set css_files = css_files + ['_static/style.css', "../../css/converse.min.css"] %}
{% set script_files = script_files + ["../../dist/converse.min.js", "../../analytics.js"] %}
{# Add some extra stuff before and use existing with 'super()' call. #}
{% block footer %}
{{ super() }}
<script>
converse.initialize({
bosh_service_url: 'https://conversejs.org/http-bind/',
});
</script>
{% endblock %}

View File

@ -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>

View File

@ -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

View File

@ -5,9 +5,9 @@
.. _builds:
=================
Generating builds
=================
===============
Creating builds
===============
.. contents:: Table of Contents
:depth: 3
@ -15,52 +15,72 @@ Generating builds
.. warning:: There current documentation in this section does not adequately
explain how to create custom bundles.
explain how to create custom builds.
.. Note:: Please make sure to read the section :doc:`development` and that you have installed
.. 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 builds and distribution files
======================================
Creating JavaScript and CSS bundles and distribution files
==========================================================
Converse.js uses `AMD (Asynchronous Modules Definition) <http://requirejs.org/docs/whyamd.html#amd>`_
to define modules and their dependencies.
Converse uses `webpack <https://webpack.js.org/>`_ to create the final JavaScript and CSS distribution files.
Dependencies can then be loaded on-the-fly with `require.js <http://requirejs.org>`_.
This is very useful during development, but when it comes to
deployement you'll usually want to create a single, minified distribution build.
The generated distribution files are all placed in the ``./dist`` directory.
The Converse repository does not include ``dist`` directory by default.
For this, the `r.js optimizer <http://requirejs.org/docs/optimization.html>`_
is used together with `almond.js <https://github.com/requirejs/almond>`_, which
is a smaller and minimal AMD API implementation that replaces require.js in builds.
To generate the ``./dist`` directory and all CSS and JavaScript bundles, simply run ``make dist``.
To create the distribution builds, simply run::
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.
make dist
.. note::
This command does the following:
If you're on Windows or don't have GNU Make installed, you can run ``npm build``
to build all the distribution files.
* It creates different builds of Converse.js in the ``./dist/`` directory.
* It bundles all the translation files in ``./locale/`` into a single file ``locales.js``.
This file can then be included via the ``<script>`` tag. See for example the ``non_amd.html`` example page.
Creating custom bundles
=======================
* Also, the CSS files in the ``./css`` directory will be minified.
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
The JavaScript build files are contained in the ``./dist`` directory:
.. code-block:: bash
jc@conversejs:~/converse.js (master)$ ls dist/
converse-mobile.js converse.min.js
converse-mobile.min.js converse.nojquery.js
converse-no-dependencies.js converse.nojquery.min.js
converse-no-dependencies.min.js locales.js
converse.js
.. _`minification`:
Creating custom builds
----------------------
One reason you might want to create your own builds, is because you want to
remove some of the core plugins of converse.js, 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.
``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.
In this section is listed all the converse.js plugins that will make up a
build.
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.
converse.js 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
@ -71,37 +91,12 @@ 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.
Minifying the CSS
-----------------
Excluding all 3rd party dependencies
------------------------------------
To only minify the CSS files, nothing else, run the following command::
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.
make cssmin
To generate this bundle, you can run:
The CSS files are minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
::
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.

View File

@ -1,8 +0,0 @@
{
"plugins": ["plugins/markdown"],
"templates": {
"default": {
"layoutFile": "_templates/jsdoc_layout.tmpl"
}
}
}

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Converse documentation build configuration file, created by
# Converse.js 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.
@ -40,17 +40,17 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'Converse'
copyright = u'2018, JC Brand'
project = u'Converse.js'
copyright = u'2017, 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'
version = '3.3.2'
# The full version, including alpha/beta/rc tags.
release = '10.1.6'
release = '3.3.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -102,13 +102,13 @@ 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"
html_logo = "_static/conversejs_small.png"
# 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",
'navbar_title': "Converse.js",
# Tab name for entire site. (Default: "Site")
'navbar_site_name': "Table of Contents",
# A list of tuples containing pages or urls to link to.
@ -177,7 +177,7 @@ html_favicon = "_static/favicon.ico"
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
html_sidebars = {'**': ['sponsors.html', 'localtoc.html', 'sourcelink.html', 'searchbox.html']}
html_sidebars = {'**': ['localtoc.html', 'sourcelink.html', 'searchbox.html']}
# Additional templates that should be rendered to pages, maps page names to
# template names.
@ -229,7 +229,7 @@ latex_elements = {
# 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',
('index', 'Conversejs.tex', u'Converse.js Documentation',
u'JC Brand', 'manual'),
]
@ -259,7 +259,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'conversejs', u'Converse Documentation',
('index', 'conversejs', u'Converse.js Documentation',
[u'JC Brand'], 1)
]
@ -273,8 +273,8 @@ man_pages = [
# (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',
('index', 'Conversejs', u'Converse.js Documentation',
u'JC Brand', 'Conversejs', 'Open Source XMPP webchat',
'Miscellaneous'),
]

File diff suppressed because it is too large Load Diff

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
.. 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>
Developer guidelines
====================
If you want to work with the non-minified JavaScript and CSS files you'll soon
notice that there are references to a missing *node_modules* directory.
Please follow the instructions below to create these directories and fetch Converse's
3rd-party dependencies.
.. note::
Windows environment: We recommend installing the required tools using `Chocolatey <https://chocolatey.org/>`_
You will need Node.js (nodejs.install), Git (git.install) and optionally to build using Makefile, GNU Make (make)
If you have trouble setting up a development environment on Windows,
please read `this post <http://librelist.com/browser//conversejs/2014/11/5/openfire-converse-and-visual-studio-questions/#b28387e7f8f126693b11598a8acbe810>`_
in the mailing list.:
Installing the development and front-end dependencies
-----------------------------------------------------
We use development tools which depend on Node.js and npm (the Node package manager).
If you don't have Node.js installed, you can download and install the latest
version `here <https://nodejs.org/download>`_.
Also make sure you have ``Git`` installed. `Details <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
.. note::
Windows users should use Chocolatey as recommended above.
.. note::
Debian & Ubuntu users : apt-get install git npm nodejs-legacy
Once you have *Node.js* and *git* installed, run the following command inside the Converse.js
directory:
::
make dev
On Windows you need to specify Makefile.win to be used by running: ::
make -f Makefile.win dev
Or alternatively, if you don't have GNU Make:
::
npm install
This will install the Node.js development tools and Converse.js's front-end dependencies.
The front-end dependencies are those javascript files on which
Converse.js directly depends and which will be loaded in the browser.
To see the dependencies, take a look at whats under the *devDependencies* key 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.js.
If these 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 write to the mailing list: conversejs@librelist.com
Loading converse.js and its dependencies
----------------------------------------
With AMD and require.js (recommended)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js uses `require.js <http://requirejs.org>`_ to asynchronously load dependencies.
If you want to develop or customize converse.js, you'll want to load the
non-minified javascript files.
Add the following two lines to the *<head>* section of your webpage:
.. code-block:: html
<link rel="stylesheet" type="text/css" media="screen" href="converse.css">
<script data-main="main" src="node_modules/requirejs/require.js"></script>
require.js will then let the main.js file be parsed (because of the *data-main*
attribute on the *script* tag), which will in turn cause converse.js to be
parsed.
Without AMD and require.js
~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse.js can also be used without require.js. If you for some reason prefer
to use it this way, please refer to
`non_amd.html <https://github.com/jcbrand/converse.js/blob/master/non_amd.html>`_
for an example of how and in what order all the JavaScript files that converse.js
depends on need to be loaded.
Brief description of converse.js's dependencies
-----------------------------------------------
Converse.js relies on the following dependencies:
* `JQuery <http://jquery.com/>`_ for DOM manipulation and `promises <http://api.jquery.com/promise/>`_.
* `moment.js <http://momentjs.com/>`_ provides a better API for handling dates and times.
* `Strophe.js <http://strophe.im/>`_ maintains the XMPP session, is used to
build XMPP stanzas, to send them, and to register handlers for received stanzas.
* `lodash <https://lodash.com/>`_ provides very useful utility functions.
* `Backbone <http://backbonejs.org/>`_ is used to model the data as Models and
Collections and to create Views that render the UI.
* `backbone.overview <http://github.com/jcbrand/backbone.overview>`_ provides
Overviews, which are to Views as Backbone Collections are to Models.
* `pluggable.js <https://github.com/jcbrand/pluggable.js>`_ is the plugin
architecture for Converse.js. It registers and initializes plugins and
allows existing attributes, functions and objects on converse.js to be
overridden inside plugins.
When submitting a pull request
------------------------------
Please follow the usual github workflow. Create your own local fork of this repository,
make your changes and then submit a pull request.
Follow the programming style guide
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please read the `style guide </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. We use Jasmine
for testing.
Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
to see how tests are implemented.
Check that the tests pass
~~~~~~~~~~~~~~~~~~~~~~~~~
Check that all tests complete sucessfully.
Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
in your browser.

View File

@ -2,31 +2,27 @@
<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:
===========
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.
Welcome to the developer documentation of converse.js. Read the documentation
linked to below, if you want to add new features or create your own customized
version of converse.js.
Converse.js itself composed of plugins, and exposes an API with which you can
create and register your own plugins. This is the recommended way to customize
or add new functionality to converse.js.
.. toctree::
:maxdepth: 2
setup_dev_environment
developer_guidelines
style_guide
plugin_development
api/index
testing
developer_api
events
other_frameworks
builds
style_guide

View File

@ -30,26 +30,29 @@ under ``docs/source``.
How to generate HTML from the source files?
===========================================
Install Dependencies
--------------------
In order to generate HTML from the source files, you need to have Sphinx and
the `Sphinx Bootstrap Theme <http://ryan-roemer.github.io/sphinx-bootstrap-theme>`_
installed.
We use `zc.buildout <http://www.buildout.org/en/latest/>`_ to install Sphinx
and the theme.
To install Sphinx, do the following::
python bootstrap.py
./bin/buildout
Generate the HTML
-----------------
After installing the dependencies, you can generate the HTML by running::
After installing the dependencies, you can generate the HTML by simply
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.

480
docs/source/events.rst Normal file
View File

@ -0,0 +1,480 @@
.. 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>
.. _`events-API`:
Events and promises
===================
Converse.js and its plugins emit various events which you can listen to via the
:ref:`listen-grouping`.
Some of these events are also available as `ES2015 Promises <http://es6-features.org/#PromiseUsage>`_,
although not all of them could logically act as promises, since some events
might be fired multpile times whereas promises are to be resolved (or
rejected) only once.
The core events, which are also promises are:
* `cachedRoster`_
* `chatBoxesFetched`_
* `controlboxInitialized`_ (only via the `converse-controlbox` plugin)
* `pluginsInitialized`_
* `roomsPanelRendered`_ (only via the `converse-muc` plugin)
* `rosterContactsFetched`_
* `rosterGroupsFetched`_
* `rosterInitialized`_
* `roster`_
* `statusInitialized`_
For more info on how to use (or add promises), you can read the
:ref:`promises-grouping` in the API documentation.
Below we will now list all events and also specify whether they are available
as promises.
List of Events (and promises)
-----------------------------
Hooking into events that Converse.js emits is a great way to extend or
customize its functionality.
From version 3.0.0 and up, it's only possible to register event handlers inside
a plugin, by using the closured ``_converse`` object. When writing a plugin,
remember that it will also have to be whitelisted, before it will be loaded.
Refer to the :ref:`whitelisted_plugins` setting.
Here follows the different events that are emitted:
afterMessagesFetched
~~~~~~~~~~~~~~~~~~~~
Emitted whenever a chat box has fetched its messages from ``sessionStorage`` and
**NOT** from the server.
This event is listened to by the ``converse-mam`` plugin to know when it can
fetch archived messages from the server.
The event handler is passed the ``Backbone.View`` instance of the relevant chat
box.
``_converse.on('afterMessagesFetched', function (chatboxview) { ... });``
.. _`cachedRoster`:
cachedRoster
~~~~~~~~~~~~
The contacts roster has been retrieved from the local cache (`sessionStorage`).
``_converse.on('cachedRoster', function (items) { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('cachedRoster').then(function () {
// Your code here...
});
See also the `roster`_ event further down.
callButtonClicked
~~~~~~~~~~~~~~~~~
When a call button (i.e. with class .toggle-call) on a chat box has been clicked.
``_converse.on('callButtonClicked', function (connection, model) { ... });``
.. _`chatBoxesFetched`:
chatBoxesFetched
~~~~~~~~~~~~~~~~
Any open chat boxes (from this current session) has been retrieved from the local cache (`sessionStorage`).
You should wait for this event or promise before attempting to do things
related to open chat boxes.
``_converse.on('chatBoxesFetched', function (items) { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('chatBoxesFetched').then(function () {
// Your code here...
});
chatBoxInitialized
~~~~~~~~~~~~~~~~~~
When a chat box has been initialized. Relevant to converse-chatview.js plugin.
``_converse.on('chatBoxInitialized', function (chatbox) { ... });``
chatBoxOpened
~~~~~~~~~~~~~
When a chat box has been opened. Relevant to converse-chatview.js plugin.
``_converse.on('chatBoxOpened', function (chatbox) { ... });``
chatRoomOpened
~~~~~~~~~~~~~~
When a chat room has been opened. Relevant to converse-chatview.js plugin.
``_converse.on('chatRoomOpened', function (chatbox) { ... });``
chatBoxClosed
~~~~~~~~~~~~~
When a chat box has been closed. Relevant to converse-chatview.js plugin.
``_converse.on('chatBoxClosed', function (chatbox) { ... });``
chatBoxFocused
~~~~~~~~~~~~~~
When the focus has been moved to a chat box. Relevant to converse-chatview.js plugin.
``_converse.on('chatBoxFocused', function (chatbox) { ... });``
chatBoxToggled
~~~~~~~~~~~~~~
When a chat box has been minimized or maximized. Relevant to converse-chatview.js plugin.
``_converse.on('chatBoxToggled', function (chatbox) { ... });``
connected
~~~~~~~~~
After connection has been established and converse.js has got all its ducks in a row.
``_converse.on('connected', function () { ... });``
contactRequest
~~~~~~~~~~~~~~
Someone has requested to subscribe to your presence (i.e. to be your contact).
``_converse.on('contactRequest', function (user_data) { ... });``
contactRemoved
~~~~~~~~~~~~~~
The user has removed a contact.
``_converse.on('contactRemoved', function (data) { ... });``
contactStatusChanged
~~~~~~~~~~~~~~~~~~~~
When a chat buddy's chat status has changed.
``_converse.on('contactStatusChanged', function (buddy) { ... });``
contactStatusMessageChanged
~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a chat buddy's custom status message has changed.
``_converse.on('contactStatusMessageChanged', function (data) { ... });``
controlboxInitialized
~~~~~~~~~~~~~~~~~~~~~
Called when the controlbox has been initialized and therefore exists.
The controlbox contains the login and register forms when
the user is logged out and a list of the user's contacts and group chats when
logged in.
``_converse.on('controlboxInitialized', function () { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('controlboxInitialized').then(function () {
// Your code here...
});
discoInitialized
~~~~~~~~~~~~~~~~
Emitted once the ``converse-disco`` plugin has been initialized and the
``_converse.disco_entities`` collection will be available and populated with at
least the service discovery features of the user's own server.
``_converse.on('discoInitialized', function () { ... });``
disconnected
~~~~~~~~~~~~
After converse.js has disconnected from the XMPP server.
``_converse.on('disconnected', function () { ... });``
initialized
~~~~~~~~~~~
Once converse.js has been initialized.
``_converse.on('initialized', function () { ... });``
See also `pluginsInitialized`_.
logout
~~~~~~
The user has logged out.
``_converse.on('logout', function () { ... });``
messageAdded
~~~~~~~~~~~~
Once a message has been added to a chat box. The passed in data object contains
a `chatbox` attribute, referring to the chat box receiving the message, as well
as a `message` attribute which refers to the Message model.
.. code-block:: javascript
_converse.on('messageAdded', function (data) {
// The message is at `data.message`
// The original chat box is at `data.chatbox`.
});
messageSend
~~~~~~~~~~~
When a message will be sent out.
``_converse.on('messageSend', function (messageText) { ... });``
noResumeableSession
~~~~~~~~~~~~~~~~~~~
When keepalive=true but there aren't any stored prebind tokens.
``_converse.on('noResumeableSession', function () { ... });``
.. _`pluginsInitialized`:
pluginsInitialized
~~~~~~~~~~~~~~~~~~
Emitted once all plugins have been initialized. This is a useful event if you want to
register event handlers but would like your own handlers to be overridable by
plugins. In that case, you need to first wait until all plugins have been
initialized, so that their overrides are active. One example where this is used
is in `converse-notifications.js <https://github.com/jcbrand/converse.js/blob/master/src/converse-notification.js>`.
``_converse.on('pluginsInitialized', function () { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('pluginsInitialized').then(function () {
// Your code here...
});
reconnecting
~~~~~~~~~~~~
Fired once converse.js has determined that it will attempt to reconnect (and
each subsequent time, if it attempts repeatedly).
reconnected
~~~~~~~~~~~
After the connection has dropped and converse.js has reconnected.
Any Strophe stanza handlers (as registered via `converse.listen.stanza`) will
have to be registered anew.
``_converse.on('reconnected', function () { ... });``
roomsAutoJoined
---------------
Emitted once any rooms that have been configured to be automatically joined,
specified via the _`auto_join_rooms` setting, have been entered.
``_converse.on('roomsAutoJoined', function () { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('roomsAutoJoined').then(function () {
// Your code here...
});
roomInviteSent
~~~~~~~~~~~~~~
After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
``_converse.on('roomInvite', function (data) { ... });``
roomInviteReceived
~~~~~~~~~~~~~~~~~~
After the user has sent out a direct invitation, to a roster contact, asking them to join a room.
``_converse.on('roomInvite', function (data) { ... });``
.. _`roomsPanelRendered`:
roomsPanelRendered
~~~~~~~~~~~~~~~~~~
Emitted once the "Rooms" panel in the control box has been rendered.
Used by `converse-bookmarks` and `converse-roomslist` to know when they can
render themselves in that panel.
``_converse.on('roomsPanelRendered', function (data) { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('roomsPanelRendered').then(function () {
// Your code here...
});
.. _`roster`:
roster
~~~~~~
When the roster has been received from the XMPP server.
``_converse.on('roster', function (items) { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('roster').then(function () {
// Your code here...
});
See also the `cachedRoster` event further up, which gets called instead of
`roster` if its already in `sessionStorage`.
.. _`rosterContactsFetched`:
rosterContactsFetched
~~~~~~~~~~~~~~~~~~~~~
Triggered once roster contacts have been fetched. Used by the
`converse-rosterview.js` plugin to know when it can start to show the roster.
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('rosterContactsFetched').then(function () {
// Your code here...
});
.. _`rosterGroupsFetched`:
rosterGroupsFetched
~~~~~~~~~~~~~~~~~~~
Triggered once roster groups have been fetched. Used by the
`converse-rosterview.js` plugin to know when it can start alphabetically
position roster groups.
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('rosterGroupsFetched').then(function () {
// Your code here...
});
.. _`rosterInitialized`:
rosterInitialized
~~~~~~~~~~~~~~~~~
The Backbone collections `RosterContacts` and `RosterGroups` have been created,
but not yet populated with data.
This event is useful when you want to create views for these collections.
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('rosterInitialized').then(function () {
// Your code here...
});
rosterPush
~~~~~~~~~~
When the roster receives a push event from server. (i.e. New entry in your buddy list)
``_converse.on('rosterPush', function (items) { ... });``
rosterReadyAfterReconnection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similar to `rosterInitialized`, but instead pertaining to reconnection. This
event indicates that the Backbone collections representing the roster and its
groups are now again available after converse.js has reconnected.
.. _`statusInitialized`:
statusInitialized
~~~~~~~~~~~~~~~~~
When the user's own chat status has been initialized.
``_converse.on('statusInitialized', function (status) { ... });``
Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
.. code-block:: javascript
_converse.api.waitUntil('statusInitialized').then(function () {
// Your code here...
});
statusChanged
~~~~~~~~~~~~~
When own chat status has changed.
``_converse.on('statusChanged', function (status) { ... });``
statusMessageChanged
~~~~~~~~~~~~~~~~~~~~
When own custom status message has changed.
``_converse.on('statusMessageChanged', function (message) { ... });``
serviceDiscovered
~~~~~~~~~~~~~~~~~
When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
``_converse.on('serviceDiscovered', function (service) { ... });``
windowStateChanged
~~~~~~~~~~~~~~~~~~
When window state has changed. Used to determine when a user left the page and when came back.
``_converse.on('windowStateChanged', function (data) { ... });``

View File

@ -2,119 +2,10 @@
<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
==================
@ -125,11 +16,39 @@ A room (aka groupchat) can be opened with a URL fragment such as `#converse/room
and a private chat with a URL fragment such as
`#converse/chat?jid=user@domain`.
Off-the-record encryption
=========================
Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to
**verify the identity** of the person you are talking to,
**plausible deniability** and **perfect forward secrecy** by generating
new encryption keys for each conversation.
In its current state, JavaScript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native "desktop" software.
This is due to its runtime malleability, the way it is "installed" (e.g.
served) and the browser's lack of cryptographic primitives needed to implement
secure crypto.
For harsh but fairly valid criticism of JavaScript cryptography, read:
`JavaScript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
To get an idea on how this applies to OTR support in Converse.js, please read
`my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you're much better off using native software.
Notifications
=============
From version 0.8.1 Converse can play a sound notification when you receive a
From version 0.8.1 Converse.js can play a sound notification when you receive a
message.
For more info, refer to the :ref:`play-sounds` configuration setting.
@ -142,16 +61,16 @@ For more info, refer to the :ref:`show-desktop-notifications` configuration sett
Multilingual Support
====================
Converse is translated into over 30 languages. Translations can be added or
updated on `Weblate <https://hosted.weblate.org/projects/conversejs/>`_.
Converse.js is translated into multiple languages. The default build,
``converse.min.js``, includes all languages.
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.
Languages increase the size of the Converse.js significantly.
If you only need one, or a subset of the available languages, it's better to
make a custom build which includes only those languages that you need.
Moderating chat rooms
====================
=====================
Here are the different commands that may be used to moderate a chat room:
@ -184,7 +103,7 @@ Here are the different commands that may be used to moderate a chatroom:
Passwordless login with client certificates
===========================================
Converse supports the SASL-EXTERNAL authentication mechanism, which can be
Converse.js supports the SASL-EXTERNAL authentication mechanism, which can be
used together with x509 client certificates to enable passwordless login or
even 2-factor authentication.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -1,4 +1,4 @@
.. Converse documentation master file, created by
.. Converse.js 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.
@ -7,20 +7,22 @@
<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
======================
=========================
Converse.js Documentation
=========================
Preface
=======
This is the official documentation for Converse. If you'd like to
This is the official documentation for Converse.js. If you'd like to
contribute, please read the :doc:`documentation` page.
You might instead be looking for the `User Manual <manual.html>`_.
Introduction
============
Converse is a free and open-source `XMPP <https://xmpp.org/about-xmpp/>`_
Converse.js is a free and open-source `XMPP <http://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
@ -44,11 +46,10 @@ Table of Contents
quickstart
features
setup
session
configuration
development
theming
security
theming
translations
troubleshooting
documentation

View File

@ -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.

186
docs/source/manual.rst Normal file
View File

@ -0,0 +1,186 @@
.. raw:: html
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/manual.rst">Edit me on GitHub</a></div>
===========================
The Converse.js User Manual
===========================
.. |br| raw:: html
<br />
.. figure:: images/homepage.jpg
:align: right
:alt: The converse.js website
The converse.js website
**Welcome to the converse.js user manual**. This manual is very much still a work
in progress and is far from complete. Please bear in mind that it's the work of volunteers.
If you have requests or suggestions on how the manual can be improved or
expanded, then please `contact me <https://opkode.com/contact.html>`_
or create a new ticket on `Github <https://github.com/jcbrand/converse.js/issues>`_.
Although converse.js can be integrated into any website, for this user manual
we'll refer to the canonical version at https://conversejs.org.
This documentation also integrates the converse.js chat client, so you can try
out some of the steps right on this page! Just click the **Toggle chat** button
at the bottom right of the page to open the so-called *control box* of the
converse.js chat client.
Registering a new chat account
==============================
.. figure:: images/register-panel.jpg
:align: left
:alt: The registration panel of the converse.js control box.
The registration panel of converse.js
With converse.js you can register a new XMPP account on any publically available XMPP provider.
To do so, click the **Register** tab on the chat client.
You will then see the *registration panel* as shown in the picture below.
Choosing your provider
----------------------
Converse.js uses a chat protocol called XMPP (also known as Jabber) which allows "federation".
This means that it's similar to email, in the sense that people signed in at
different XMPP chat providers can still chat with one another.
For example, if you have a Yahoo! email account, you can send and receive emails from
a friend with a Google email account. In the same way, if you have a chat
account from **Conversejs.org**, you can send and receive chat messages with a
friend who has an account at `Jappix.com <https://jappix.com>`_.
There are many free providers online which allow you to register a new account.
You can see a list of some of them at `xmpp.net <https://xmpp.net/directory.php>`_.
The `xmpp.net <https://xmpp.net/directory.php>`_ website provides a security grading
for the XMPP servers of the providers, which is very useful. They are however sometimes
slow to add new servers to the list.
A larger list of XMPP providers is also available at `list.jabber.net <https://list.jabber.at/>`_.
You can find the domain name for a server under the *Domain* column at
`xmpp.net <https://xmpp.net/directory.php>`_. or the *Server* column at
`list.jabber.net <https://list.jabber.at/>`_.
Once you know which XMPP provider you'd like to use, you can type its domain
name and click the **Fetch registration form** button.
|br|
.. figure:: images/register-form.jpg
:align: left
:alt: The registration form for an XMPP account at conversejs.org
The registration form
Filling out the registration form
---------------------------------
After you've clicked **Fetch registration form**, the chat client will contact
the chat provider, ask for its registration form and then present it to you.
Different chat providers have different registration forms, but they're all
relatively similar.
Check the security score
~~~~~~~~~~~~~~~~~~~~~~~~
At the top of the form you'll see a colored bar containing the text **xmpp.net score**.
This shows the security score for this server as determined by `xmpp.net <https://xmpp.net>`_
where you can test out a server for yourself. You should generally avoid providers with
a poor security score (colored in red).
Choosing a username
~~~~~~~~~~~~~~~~~~~
As you can see in the registration form, the **username** consists of two
parts separated with an **@** sign, similar to an email address.
The first part is your unique *handle* which you need to choose. The second part
is the domain name of the chat provider, the one which you chose in the previous step
when you fetched the registration form.
When you want to give someone your XMPP chat username, or when you want to add
someone else as a contact, you need to specify it in full, like you would an email address.
Once you've chosen your user name and password, click **Register**. If
Successful, you'll be automatically logged in to your new account.
|br|
.. figure:: images/add-contact.png
:align: left
:alt: Adding a contact in converse.js
The form for adding a new contact
Adding a contact
================
In order to start chatting with someone, you first need to add them as a contact.
To do this, click the **Add a contact** link in the **Contacts** tab. This will
slide open a dropdown in which you can type the username of the person you'd
like to add.
Remember, an XMPP username (also called a JID or Jabber ID) is similar to an
email address, in that you have both the user's *handle* and the *domain name*
of the provider, separated with an **@** sign.
Once you've typed the username and clicked submit, your request will be sent to
this person. If they are online, they will immediately be notified of your
request, otherwise they'll see it next time they come online.
Technically, when you add someone as a contact, you're doing two things. Firstly,
you are adding the contact to your *roster* (think of it as an address book) and secondly
you are asking to be notified whenever that person comes online.
.. figure:: images/pending-contact.jpg
:align: left
:alt: A pending contact
A pending contact
A pending contact
-----------------
The person you are adding as a contact has the option to either accept or decline your request.
Until that decision has been made, they will appear in your roster as a
so-called *pending* contact. In other words, their final status is pending on whether
they accept or decline your request.
.. figure:: images/ungrouped-contact.png
:align: right
:alt: A normal, ungrouped contact
A normal contact
A normal contact
----------------
If the person accepts your contact request, they will get a *chat status
indicator* in your roster and will also become clickable. Clicking on the name
of the user will open a chat box in which you can then start chatting with that
user.
.. figure:: images/remove-contact.png
:align: left
:alt: Removing a contact
Removing a contact
Removing a contact
==================
To remove a contact, hover your mouse over their name and then click on the
trash icon. You will be prompted to confirm, and if you do, the contact will no
longer be visible in your roster.

View File

@ -1,6 +1,6 @@
.. 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>
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
Integrating converse.js into other frameworks
=============================================
@ -58,6 +58,7 @@ Below is an example code that wraps converse.js as an angular.js service.
"converse-mam", // XEP-0313 Message Archive Management
"converse-muc", // XEP-0045 Multi-user chat
"converse-vcard", // XEP-0054 VCard-temp
"converse-otr", // Off-the-record encryption for one-on-one messages
"converse-register", // XEP-0077 In-band registration
"converse-ping", // XEP-0199 XMPP Ping
"converse-notification", // HTML5 Notifications
@ -116,6 +117,7 @@ your components, for example:
'auto_reconnect': true,
'bosh_service_url': bosh_url,
'jid': bare_jid,
'keepalive': true,
'credentials_url': credentials_url,
'whitelisted_plugins': ['conversejs-angular-service']
});

View File

@ -1,6 +1,6 @@
.. 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>
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
.. _`writing-a-plugin`:
@ -10,75 +10,51 @@ 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.
Converse.js exposes a plugin architecture through which developers can modify
and extend its functionality.
There are only a few files that are included in the default build of Converse
which aren't plugins.
Using plugins is good engineering practice, and using them is the *only* recommended
way of changing converse.js or adding new features to it.
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.
In particular, plugins have the following advantages:
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
The main benefit of plugins is their *isolation of concerns* (and features).
From this benefit flows various 2nd degree 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.
upgrade path by avoiding touching converse.js'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
Each plugin comes in its own file, and converse.js's plugin architecture,
called `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.
Converse.js itself is composed out of plugins and uses pluggable.js. Take a look at the
`src <https://github.com/jcbrand/converse.js/tree/master/src>`_ directory. All
the files that follow the pattern `converse-*.js` are plugins.
Plugins (by way of Pluggable.js) enable developers to extend and override existing objects,
functions and the `Backbone <http://backbonejs.org/>`_ models and views that make up
Converse.js.
Besides that, in plugins you can also write new Backbone (or other) models and views,
in order to add a new functionality.
To more deeply understand how this plugin architecture works, please read the
`pluggable.js documentation <https://jcbrand.github.io/pluggable.js/>`_
and to understand its inner workings, please refer to the `annotated source code
<https://jcbrand.github.io/pluggable.js/docs/pluggable.html>`_.
.. note:: **Trying out a plugin in JSFiddle**
Because Converse consists only of JavaScript, HTML and CSS (with no backend
Because Converse.js 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
Here's a Fiddle with a Converse.js 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
The rest of this document explains how to write a plugin for Converse.js and
ends with a documented example of a plugin.
There is a `Yeoman <http://yeoman.io/>`_ code generator, called
@ -95,12 +71,12 @@ 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``.
You register a converse.js 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.
by the website to configure and initialize Converse.js itself.
Here's an example code snippet:
@ -125,7 +101,7 @@ Here's an example code snippet:
Whitelisting of plugins
-----------------------
As of Converse 3.0.0 and higher, plugins need to be whitelisted before they
As of converse.js 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.
@ -136,13 +112,9 @@ 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
included in the default, open-source version of converse.js, 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.
`./src/converse-core.js <https://github.com/jcbrand/converse.js/blob/master/src/converse-core.js>`_.
Security and access to the inner workings
-----------------------------------------
@ -151,7 +123,7 @@ 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,
This inner ``_converse`` object contains all the Backbone models and views,
as well as various other attributes and functions.
Within a plugin, you will have access to this internal
@ -162,157 +134,88 @@ 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.
Loading a plugin module
-----------------------
Converse.js uses the UMD (Universal Modules Definition) as its module syntax.
This makes modules loadable via `require.js`, `webpack` or other module
loaders, but also includable as old-school `<script>` tags in your HTML.
Here's an example of the plugin shown above wrapped inside a UMD module:
.. code-block:: javascript
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module called "myplugin"
define(["converse"], factory);
} else {
// Browser globals. If you're not using a module loader such as require.js,
// then this line below executes. Make sure that your plugin's <script> tag
// appears after the one from converse.js.
factory(converse);
}
}(this, function (converse) {
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
},
});
});
Accessing 3rd party libraries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Immediately inside the module shown above you can access 3rd party libraries (such
dayjs) via the ``converse.env`` map.
moment and lodash) via the ``converse.env`` map.
The code for it would look something like this:
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;
var Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
$msg = converse.env.$msg,
$pres = converse.env.$pres,
$build = converse.env.$build,
b64_sha1 = converse.env.b64_sha1,
_ = converse.env._,
moment = converse.env.moment;
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
--------------------
Overrides
---------
Converse uses `lit-html <https://lit-html.polymer-project.org/guide>`_
templates and templates are imported as separate files.
Plugins can override core code or code from other plugins. Refer to the full
example at the bottom for code details.
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
Use the ``overrides`` functionality 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``
and prone to bugs when Converse.js 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
A better approach is to listen to the events emitted by Converse.js, 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
@ -340,39 +243,37 @@ 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
----------------------------------------------
Extending converse.js's configuration settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converse comes with various :ref:`configuration-settings` that can be used to
Converse.js 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.
`converse.initialize` (see :ref:`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.
these settings with the `_converse.api.settings.update` method (see
:ref:`settings-update`).
Exposing promises
-----------------
~~~~~~~~~~~~~~~~~
Converse has a `waitUntil </docs/html/api/-_converse.api.html#.waitUntil>`_ API method
Converse.js has a ``waitUntil`` API method (see :ref:`waituntil-grouping`)
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>`_.
``_converse.api.promises.add`` (see :ref:`promises-grouping`).
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
promises are resolved. You do this by calling ``_converse.api.emit``, 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
Due to the asynchronous nature of XMPP, many subroutines in Converse.js 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
@ -395,9 +296,9 @@ In this case, you should first listen for the ``connection`` event, and then do
converse.plugins.add('myplugin', {
initialize: function () {
const _converse = this._converse;
var _converse = this._converse;
_converse.api.listen.on('connected', function () {
_converse.on('connected', function () {
_converse.api.archive.query({'with': 'admin2@localhost'});
});
}
@ -431,7 +332,7 @@ method of the plugin:
.. code-block:: javascript
_converse.api.listen.on('chatBoxOpened', function renderMinimizeButton (view) {
_converse.on('chatBoxOpened', function renderMinimizeButton (view) {
// Inserts a "minimize" button in the chatview's header
// Implementation code removed for brevity
@ -446,130 +347,67 @@ 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 refer to the :ref:`events-API` section of the documentation 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
-----------------
A full 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";
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module called "myplugin"
define(["converse"], factory);
} else {
// Browser globals. If you're not using a module loader such as require.js,
// then this line below executes. Make sure that your plugin's <script> tag
// appears after the one from converse.js.
factory(converse);
}
}(this, function (converse) {
// 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;
var Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
$msg = converse.env.$msg,
$pres = converse.env.$pres,
$build = converse.env.$build,
b64_sha1 = converse.env.b64_sha1,
_ = converse.env._,
moment = converse.env.moment;
// The following line registers your plugin.
converse.plugins.add("myplugin", {
/* Dependencies are other plugins which might be
/* Optional 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
* this plugin. They are called "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.
* NB: These plugins need to have already been loaded via require.js.
*
* It's possible to make these dependencies "non-optional".
* It's possible to make optional 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: [],
'dependencies': [],
/* Converse's plugin mechanism will call the initialize
/* Converse.js's plugin mechanism will call the initialize
* method on any plugin (if it exists) as soon as the plugin has
* been loaded.
*/
initialize: function () {
'initialize': function () {
/* Inside this method, you have access to the private
* `_converse` object.
*/
const _converse = this._converse;
var _converse = this._converse;
_converse.log("The \"myplugin\" plugin is being initialized");
/* From the `_converse` object you can get any configuration
@ -604,11 +442,11 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
* _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.
* promise by calling `_converse.api.emit`, which will also
* emit an event with the same name as the promise.
* For example:
*
* _converse.api.trigger('operationCompleted');
* _converse.api.emit('operationCompleted');
*
* Other plugins can then either listen for the event
* `operationCompleted` like so:
@ -619,22 +457,54 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
*
* _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
/* If you want to override some function or a Backbone model or
* view defined elsewhere in converse.js, then you do that under
* the "overrides" namespace.
*/
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;
});
'overrides': {
/* For example, the private *_converse* object has a
* method "onConnected". You can override that method as follows:
*/
'onConnected': function () {
// Overrides the onConnected method in converse.js
// Top-level functions in "overrides" are bound to the
// inner "_converse" object.
var _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 ...
},
/* Override converse.js's XMPPStatus Backbone model so that we can override the
* function that sends out the presence stanza.
*/
'XMPPStatus': {
'sendPresence': function (type, status_message, jid) {
// The "_converse" object is available via the __super__
// attribute.
var _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);
// Custom code can come here ...
}
}
}
});
}));

View File

@ -9,96 +9,45 @@ 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.
Use the content delivery network
--------------------------------
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/>`_,
Converse.js 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
* https://cdn.conversejs.org/css/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.js you can put the version in the URL, like so:
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
* https://cdn.conversejs.org/3.0.3/dist/converse.min.js
* https://cdn.conversejs.org/3.0.3/css/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>
<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/css/converse.min.css">
<script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
Option 2: Download the builds from Github
*****************************************
.. note:: For the fullscreen version of converse.js, replace
``converse.min.js`` with ``inverse.min.js`` and ``converse.min.css`` with
``inverse.min.css``.
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.
.. note:: Instead of always loading the latest version of Converse.js via the
CDN, it's generally better to load a specific version (preferably the
latest one), to avoid breakage when new backwards-incompatible versions are
released.
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.
Initializing Converse.js
------------------------
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.
You'll then need to initialize Converse.js with configuration settings relevant to your requirements.
Refer to the :ref:`configuration-settings` section for info on all the available configuration settings.
To quickly get started, you can put the following JavaScript code at the
bottom of your page (after the closing *</body>* element)::
@ -111,49 +60,89 @@ bottom of your page (after the closing *</body>* element)::
</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.
Converse.js repository may serve as a nice usable example.
Alternative builds of Converse.js
=================================
The minified ``.js`` and ``.css`` files provide the same functionality as is available
on the `conversejs.org <https://conversejs.org>`_ website. Useful for testing or demoing.
Converse.js is composed out of plugins, and you are able to exclude certain
plugins (and to include your own new plugins) when creating a build. This
enables you to create your own custom builds of Converse.js that differ from
the standard one.
Besides the standard build, the Converse.js repository includes configuration
for certain other non-standard builds, which we'll now mention below.
Mobile version
--------------
Besides the default build mentioned above, there is a build intended for mobile
websites, called ``converse-mobile.min.js``.
Take a look at the ``mobile.html`` file in the Converse.js repository
for an example of this build being used. There's an additional CSS file called
``mobile.min.css`` which should be used with the mobile build.
When you load `conversejs.org <https://conversejs.org>`_ with a mobile device
then the mobile JavaScript build and its CSS will be used.
Excluding all 3rd party dependencies
------------------------------------
Then there is also a build that contains no 3rd party dependencies, called
``converse-no-dependencies.min.js`` and which is used in the ``non_amd.html``
page in the repository.
Headless build
--------------
There is also the option of making a headless build of converse.js.
This means a build without any UI but still containing core functionality of
maintaining a roster, chat boxes and messages.
The file `src/headless.js <https://github.com/jcbrand/converse.js/blob/master/src/headless.js>`_
is used to determine which plugins are included in the build.
Unfortunately it's currently not yet possible to include Multi-user chat (MUC)
functionality in the headless build. This is because both the UI and core
functionality is still contained in one plugin and would first need to be
split up into two parts, with the UI part dropped for this build.
Fullscreen version
------------------
Converse also comes in a fullscreen version.
A hosted version is available online at `conversejs.org/fullscreen <https://conversejs.org/fullscreen.html>`_.
Converse.js also comes in a fullscreen version (often referred to as Inverse).
A hosted version is available online at `inverse.chat <https://inverse.chat>`_.
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`.
:ref:`view_mode` and including the right CSS file.
For example::
For the default "overlay" version, ``converse.css`` is used, and for the
"fullscreen" version ``inverse.css`` is used.
We'd like to eventually not require two different CSS files, and to allow you
to seamlessly switch between the different view modes.
To generate the headless build, run ``make dist/converse-headless.js`` and/or
``make dist/converse-headless.min.js``.
<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>`
Perhaps you want to create your own custom build of Converse.js? Then head over
to the :doc:`builds` section, or more generally the :doc:`development`
documentation.
Do you want to know how to theme Converse? Then read the :doc:`theming <theming>`
Do you want to know how to theme Converse.js? Then read the :doc:`theming`
documentation.

View File

@ -1,18 +1,18 @@
.. 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>
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.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.
Converse.js 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
The data-structures of Converse.js 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
In an environment where, besides Converse.js, 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.
@ -22,18 +22,18 @@ 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
which attempt to access Converse.js'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:
As of version 3.0.0, the following actions were taken to harden Converse.js against attacks:
Separate code/data into public and private parts
------------------------------------------------
1. Encapsulate Converse's data structures into a private closured object (named ``_converse``).
1. Encapsulate Converse.js'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
@ -46,7 +46,7 @@ Restrict access to private code/data
(otherwise the whitelist could be circumvented).
.. note::
Care should be taken when using a custom build of Converse where some
Care should be taken when using a custom build of Converse.js 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.
@ -71,7 +71,7 @@ Other considerations
Locally cached data
-------------------
Besides the "hot" data stored in models and collections, which are all
Besides the "hot" data stored in Backbone 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.
@ -81,12 +81,12 @@ 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.
versions of Converse.js, 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
Therefore, the best defence as website host is to avoid serving Converse.js 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.

View File

@ -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>`_

Some files were not shown because too many files have changed in this diff Show More