Skip to content

Commit

Permalink
Merge branch '4.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
Flowdalic committed Feb 22, 2018
2 parents a48e8ef + e1eb2d4 commit 026f3a2
Show file tree
Hide file tree
Showing 34 changed files with 2,250 additions and 3 deletions.
3 changes: 3 additions & 0 deletions documentation/extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,14 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental
| [Internet of Things - Discovery](iot.md) | [XEP-0347](http://xmpp.org/extensions/xep-0347.html) | Describes how Things can be installed and discovered by their owners. |
| Client State Indication | [XEP-0352](http://xmpp.org/extensions/xep-0352.html) | A way for the client to indicate its active/inactive state. |
| [Push Notifications](pushnotifications.md) | [XEP-0357](http://xmpp.org/extensions/xep-0357.html) | Defines a way to manage push notifications from an XMPP Server. |
| Stable and Unique Stanza IDs | [XEP-0359](http://xmpp.org/extensions/xep-0359.html) | This specification describes unique and stable IDs for messages. |
| HTTP File Upload | [XEP-0363](http://xmpp.org/extensions/xep-0363.html) | Protocol to request permissions to upload a file to an HTTP server and get a shareable URL. |
| [Spoiler Messages](spoiler.md) | [XEP-0382](http://xmpp.org/extensions/xep-0382.html) | Indicate that the body of a message should be treated as a spoiler |
| [Multi-User Chat Light](muclight.md) | [XEP-xxxx](http://mongooseim.readthedocs.io/en/latest/open-extensions/xeps/xep-muc-light.html) | Multi-User Chats for mobile XMPP applications and specific enviroment. |
| [OMEMO Multi End Message and Object Encryption](omemo.md) | [XEP-XXXX](https://conversations.im/omemo/xep-omemo.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). |
| [Consistent Color Generation](consistent_colors.md) | [XEP-0392](http://xmpp.org/extensions/xep-0392.html) | Generate consistent colors for identifiers like usernames to provide a consistent user experience. |
| Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers |
| [Message Markup](messagemarkup.md) | [XEP-0394](http://xmpp.org/extensions/xep-0394.html)| Style message bodies while keeping body and markup information separated. |


Legacy Smack Extensions and currently supported XEPs of smack-legacy
Expand Down
68 changes: 68 additions & 0 deletions documentation/extensions/messagemarkup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Message Markup
==============

[Back](index.md)

[Message Markup (XEP-0394)](https://xmpp.org/extensions/xep-0394.html) can be used as a an alternative to XHTML-IM to style messages, while keeping the body and markup information strictly separated.
This implementation can *not* be used to render message bodies, but will offer a simple to use interface for creating ExtensionElements which encode the markup information.

## Usage

The most important class is the `MarkupElement` class, which contains a Builder.

To start creating a Message Markup Extension, call `MarkupElement.getBuilder()`.
(Almost) all method calls documented below will be made on the builder.

Whenever a method call receives a `start` and `end` index, `start` represents the first character, which is affected by the styling, while `end` is the character *after* the last affected character.

### Inline styling

Currently there are 3 styles available:
* *emphasis*, which should be rendered by a client as *italic*, or **bold**
* *code*, which should be rendered in `monospace`
* *deleted*, which should be rendered as ~~strikethrough~~.

Those styles are available by calling `builder.setEmphasis(int start, int end)`,
`builder.setDeleted(int start, int end)` and `builder.setCode(int start, int end)`.

If you want to apply multiple inline styles to a section, you can do the following:
```
Set<SpanElement.SpanStyle> spanStyles = new HashSet<>();
styles.add(SpanElement.SpanStyle.emphasis);
styles.add(SpanElement.SpanStyle.deleted);
builder.addSpan(start, end, spanStyles);
```

Note, that spans cannot overlap one another.

### Block Level Styling

Available block level styles are:
* Code blocks, which should be rendered as
```
blocks
of
code
```

* Itemized lists, which should render as
* Lists
* with possibly multiple
* entries

* Block Quotes, which should be rendered by the client
> as quotes, which
>> also can be nested
To mark a section as code block, call `builder.setCodeBlock(start, end)`.

To create a list, call `MarkupElement.Builder.ListBuilder lbuilder = builder.beginList()`, which will return a list builder.
On this you can call `lbuilder.addEntry(start, end)` to add an entry.

Note: If you add an entry, the start value MUST be equal to the end value of the previous added entry!

To end the list, call `lbuilder.endList()`, which will return the MessageMarkup builder.

To create a block quote, call `builder.setBlockQuote(start, end)`.

Note that block level elements MUST NOT overlap each other boundaries, but may be fully contained (nested) within each other.
33 changes: 33 additions & 0 deletions documentation/extensions/spoiler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Spoiler Messages
================

[Back](index.md)

Spoiler Messages can be used to indicate that the body of a message is a spoiler and should be displayed as such.

## Usage

To get an instance of the SpoilerManager, call
```
SpoilerManager manager = SpoilerManager.getInstanceFor(connection);
```
This will automatically add Spoilers to the list of supported features of your client.

The manager can then be used to add SpoilerElements to messages like follows:
```
Message message = new Message();
// spoiler without hint
SpoilerElement.addSpoiler(message);
// spoiler with hint about content
SpoilerElement.addSpoiler(message, "End of Love Story");
// spoiler with localized hint
SpoilerElement.addSpoiler(message, "de", "Der Kuchen ist eine Lüge");
```

To get Spoilers from a message call
```
Map<String, String> spoilers = SpoilerElement.getSpoilers(message);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
*
* Copyright © 2018 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.message_markup.element;

import org.jivesoftware.smack.util.XmlStringBuilder;

public class BlockQuoteElement implements MarkupElement.BlockLevelMarkupElement {

public static final String ELEMENT = "bquote";

private final int start, end;

/**
* Create a new Block Quote element.
*
* @param start start index
* @param end end index
*/
public BlockQuoteElement(int start, int end) {
this.start = start;
this.end = end;
}

@Override
public int getStart() {
return start;
}

@Override
public int getEnd() {
return end;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.attribute(ATTR_START, getStart());
xml.attribute(ATTR_END, getEnd());
xml.closeEmptyElement();
return xml;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
*
* Copyright © 2018 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.message_markup.element;

import org.jivesoftware.smack.util.XmlStringBuilder;

public class CodeBlockElement implements MarkupElement.BlockLevelMarkupElement {

public static final String ELEMENT = "bcode";

private final int start, end;

/**
* Create a new Code Block element.
*
* @param start start index
* @param end end index
*/
public CodeBlockElement(int start, int end) {
this.start = start;
this.end = end;
}

@Override
public int getStart() {
return start;
}

@Override
public int getEnd() {
return end;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.attribute(ATTR_START, getStart());
xml.attribute(ATTR_END, getEnd());
xml.closeEmptyElement();
return xml;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
*
* Copyright © 2018 Paul Schaub
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.message_markup.element;

import java.util.Collections;
import java.util.List;

import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

public class ListElement implements MarkupElement.MarkupChildElement {

public static final String ELEMENT = "list";
public static final String ELEM_LI = "li";

private final int start, end;
private final List<ListEntryElement> entries;

/**
* Create a new List element.
*
* @param start start index of the list
* @param end end index of the list
* @param entries list entries
*/
public ListElement(int start, int end, List<ListEntryElement> entries) {
this.start = start;
this.end = end;
this.entries = Collections.unmodifiableList(entries);
}

@Override
public int getStart() {
return start;
}

@Override
public int getEnd() {
return end;
}

/**
* Return a list of all list entries.
*
* @return entries
*/
public List<ListEntryElement> getEntries() {
return entries;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public CharSequence toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.attribute(ATTR_START, getStart());
xml.attribute(ATTR_END, getEnd());
xml.rightAngleBracket();

for (ListEntryElement li : getEntries()) {
xml.append(li.toXML());
}

xml.closeElement(this);
return xml;
}

public static class ListEntryElement implements NamedElement {

private final int start;

/**
* Create a new ListEntry element.
*
* @param start start index
*/
public ListEntryElement(int start) {
this.start = start;
}

/**
* Return the start index of this entry.
* @return start index
*/
public int getStart() {
return start;
}

@Override
public String getElementName() {
return ELEM_LI;
}

@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.attribute(ATTR_START, getStart());
xml.closeEmptyElement();
return xml;
}
}
}
Loading

0 comments on commit 026f3a2

Please sign in to comment.