Skip to content

Commit

Permalink
Merge pull request #59 from contentstack/master
Browse files Browse the repository at this point in the history
back merge to next
  • Loading branch information
reeshika-h authored Jul 16, 2024
2 parents 309cc37 + e07766b commit 81a8f32
Show file tree
Hide file tree
Showing 7 changed files with 604 additions and 7 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# CHANGELOG

## Version 3.15.1

### Date: 24-June-2024

- added support to convert json to html

---

## Version 3.15.0

### Date: 20-May-2024
Expand Down
19 changes: 12 additions & 7 deletions contentstack/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ android.buildFeatures.buildConfig true
mavenPublishing {
publishToMavenCentral(SonatypeHost.DEFAULT)
signAllPublications()
coordinates("com.contentstack.sdk", "android", "3.15.0")
coordinates("com.contentstack.sdk", "android", "3.15.1")

pom {
name = "contentstack-android"
Expand Down Expand Up @@ -76,6 +76,11 @@ android {
// }
}
}
// signing {
// // Specify key and other signing details
// useGpgCmd()
// sign configurations.archives
// }
signingConfigs {
debug {
storeFile file("../key.keystore")
Expand Down Expand Up @@ -111,12 +116,12 @@ android {
testCoverageEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

buildConfigField "String", "host", localProperties['host']
buildConfigField "String", "APIKey", localProperties['APIKey']
buildConfigField "String", "deliveryToken", localProperties['deliveryToken']
buildConfigField "String", "environment", localProperties['environment']
buildConfigField "String", "contentTypeUID", localProperties['contentType']
buildConfigField "String", "assetUID", localProperties['assetUid']
buildConfigField "String", "host", localProperties['host']
buildConfigField "String", "APIKey", localProperties['APIKey']
buildConfigField "String", "deliveryToken", localProperties['deliveryToken']
buildConfigField "String", "environment", localProperties['environment']
buildConfigField "String", "contentTypeUID", localProperties['contentType']
buildConfigField "String", "assetUID", localProperties['assetUid']
}
release {
minifyEnabled false
Expand Down
216 changes: 216 additions & 0 deletions contentstack/src/main/java/com/contentstack/sdk/DefaultOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package com.contentstack.sdk;

import android.text.TextUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

public class DefaultOption implements Option {
@Override
public String renderOptions(JSONObject embeddedObject, Metadata metadata) {
switch (metadata.getStyleType()) {
case BLOCK:
return "<div><p>" + findTitleOrUid(embeddedObject) + "</p><div><p>Content type: <span>" + embeddedObject.optString("_content_type_uid") + "</span></p></div>";
case INLINE:
return "<span>" + findTitleOrUid(embeddedObject) + "</span>";
case LINK:
return "<a href=\"" + embeddedObject.optString("url") + "\">" + findTitleOrUid(embeddedObject) + "</a>";
case DISPLAY:
return "<img src=\"" + embeddedObject.optString("url") + "\" alt=\"" + findAssetTitle(embeddedObject) + "\" />";
default:
return "";
}
}

@Override
public String renderMark(MarkType markType, String text) {
switch (markType) {
case SUPERSCRIPT:
return "<sup>" + text + "</sup>";
case SUBSCRIPT:
return "<sub>" + text + "</sub>";
case INLINECODE:
return "<span>" + text + "</span>";
case STRIKETHROUGH:
return "<strike>" + text + "</strike>";
case UNDERLINE:
return "<u>" + text + "</u>";
case ITALIC:
return "<em>" + text + "</em>";
case BOLD:
return "<strong>" + text + "</strong>";
case BREAK:
return "<br />" + text.replace("\n", "");
default:
return text;
}
}

private String escapeInjectHtml(JSONObject nodeObj, String nodeType) {
String injectedHtml = getNodeStr(nodeObj, nodeType);
return TextUtils.htmlEncode(injectedHtml);
}

@Override
public String renderNode(String nodeType, JSONObject nodeObject, NodeCallback callback) {
String strAttrs = strAttrs(nodeObject);
String children = callback.renderChildren(nodeObject.optJSONArray("children"));
switch (nodeType) {
case "p":
return "<p" + strAttrs + ">" + children + "</p>";
case "a":
return "<a" + strAttrs + " href=\"" + escapeInjectHtml(nodeObject, "href") + "\">" + children + "</a>";
case "img":
String assetLink = getNodeStr(nodeObject, "asset-link");
if (!assetLink.isEmpty()) {
JSONObject attrs = nodeObject.optJSONObject("attrs");
if (attrs.has("link")) {
return "<a href=\"" + escapeInjectHtml(nodeObject, "link") + "\" >" + "<img" + strAttrs + " src=\"" + escapeInjectHtml(nodeObject, "asset-link") + "\" />" + children + "</a>";
}
return "<img" + strAttrs + " src=\"" + escapeInjectHtml(nodeObject, "asset-link") + "\" />" + children;
}
return "<img" + strAttrs + " src=\"" + escapeInjectHtml(nodeObject, "src") + "\" />" + children;
case "embed":
return "<iframe" + strAttrs + " src=\"" + escapeInjectHtml(nodeObject, "src") + "\"" + children + "</iframe>";
case "h1":
return "<h1" + strAttrs + ">" + children + "</h1>";
case "h2":
return "<h2" + strAttrs + ">" + children + "</h2>";
case "h3":
return "<h3" + strAttrs + ">" + children + "</h3>";
case "h4":
return "<h4" + strAttrs + ">" + children + "</h4>";
case "h5":
return "<h5" + strAttrs + ">" + children + "</h5>";
case "h6":
return "<h6" + strAttrs + ">" + children + "</h6>";
case "ol":
return "<ol" + strAttrs + ">" + children + "</ol>";
case "ul":
return "<ul" + strAttrs + ">" + children + "</ul>";
case "li":
return "<li" + strAttrs + ">" + children + "</li>";
case "hr":
return "<hr" + strAttrs + " />";
case "table":
return "<table " + strAttrs + ">" + children + "</table>";
case "thead":
return "<thead " + strAttrs + ">" + children + "</thead>";
case "tbody":
return "<tbody" + strAttrs + ">" + children + "</tbody>";
case "tfoot":
return "<tfoot" + strAttrs + ">" + children + "</tfoot>";
case "tr":
return "<tr" + strAttrs + ">" + children + "</tr>";
case "th":
return "<th" + strAttrs + ">" + children + "</th>";
case "td":
return "<td" + strAttrs + ">" + children + "</td>";
case "blockquote":
return "<blockquote" + strAttrs + ">" + children + "</blockquote>";
case "code":
return "<code" + strAttrs + ">" + children + "</code>";
case "reference":
return "";
case "fragment":
return "<fragment" + strAttrs + ">" + children + "</fragment>";
default:
return children;
}
}

String strAttrs(JSONObject nodeObject) {
StringBuilder result = new StringBuilder();
if (nodeObject.has("attrs")) {
JSONObject attrsObject = nodeObject.optJSONObject("attrs");
if (attrsObject != null && attrsObject.length() > 0) {
for (Iterator<String> it = attrsObject.keys(); it.hasNext(); ) {
String key = it.next();
Object objValue = attrsObject.opt(key);
String value = objValue.toString();
// If style is available, do styling calculations
if (Objects.equals(key, "style")) {
String resultStyle = stringifyStyles(attrsObject.optJSONObject("style"));
result.append(" ").append(key).append("=\"").append(resultStyle).append("\"");
} else {
String[] ignoreKeys = {"href", "asset-link", "src", "url"};
ArrayList<String> ignoreKeysList = new ArrayList<>(Arrays.asList(ignoreKeys));
if (!ignoreKeysList.contains(key)) {
result.append(" ").append(key).append("=\"").append(value).append("\"");
}
}
}
}
}
return result.toString();
}

private String stringifyStyles(JSONObject style) {
Map<String, String> styleMap = new HashMap<>();

// Convert JSONObject to a Map
Iterator<String> keys = style.keys();
while (keys.hasNext()) {
String key = keys.next();
String value = null;
try {
value = style.getString(key);
} catch (JSONException e) {
throw new RuntimeException(e);
}
styleMap.put(key, value);
}

StringBuilder styleString = new StringBuilder();

for (Map.Entry<String, String> entry : styleMap.entrySet()) {
String property = entry.getKey();
String value = entry.getValue();

styleString.append(property).append(": ").append(value).append("; ");
}

return styleString.toString();
}

private String getNodeStr(JSONObject nodeObject, String key) {
String herf = nodeObject.optJSONObject("attrs").optString(key); // key might be [href/src]
if (herf == null || herf.isEmpty()) {
herf = nodeObject.optJSONObject("attrs").optString("url");
}
return herf;
}

protected String findTitleOrUid(JSONObject embeddedObject) {
String _title = "";
if (embeddedObject != null) {
if (embeddedObject.has("title") && !embeddedObject.optString("title").isEmpty()) {
_title = embeddedObject.optString("title");
} else if (embeddedObject.has("uid")) {
_title = embeddedObject.optString("uid");
}
}
return _title;
}

protected String findAssetTitle(JSONObject embeddedObject) {
String _title = "";
if (embeddedObject != null) {
if (embeddedObject.has("title") && !embeddedObject.optString("title").isEmpty()) {
_title = embeddedObject.optString("title");
} else if (embeddedObject.has("filename")) {
_title = embeddedObject.optString("filename");
} else if (embeddedObject.has("uid")) {
_title = embeddedObject.optString("uid");
}
}
return _title;
}
}
104 changes: 104 additions & 0 deletions contentstack/src/main/java/com/contentstack/sdk/Metadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.contentstack.sdk;

import java.util.jar.Attributes;

public class Metadata {
String text;
String itemType;
String itemUid;
String contentTypeUid;
StyleType styleType;
String outerHTML;
Attributes attributes;

public Metadata(String text, String itemType, String itemUid, String contentTypeUid,
String styleType, String outerHTML, Attributes attributes) {
this.text = text;
this.itemType = itemType;
this.itemUid = itemUid;
this.contentTypeUid = contentTypeUid;
this.styleType = StyleType.valueOf(styleType.toUpperCase());
this.outerHTML = outerHTML;
this.attributes = attributes;
}

@Override
public String toString() {
return "EmbeddedObject{" +
"text='" + text + '\'' +
"type='" + itemType + '\'' +
", uid='" + itemUid + '\'' +
", contentTypeUid='" + contentTypeUid + '\'' +
", sysStyleType=" + styleType +
", outerHTML='" + outerHTML + '\'' +
", attributes='" + attributes + '\'' +
'}';
}

/**
* The getText() function returns the value of the text variable.
*
* @return The method is returning a String value.
*/
public String getText() {
return text;
}

/**
* The getItemType() function returns the type of an item.
*
* @return The method is returning the value of the variable "itemType".
*/
public String getItemType() {
return itemType;
}

/**
* The function returns the attributes of an object.
*
* @return The method is returning an object of type Attributes.
*/
public Attributes getAttributes() {
return attributes;
}

/**
* The getItemUid() function returns the itemUid value.
*
* @return The method is returning the value of the variable "itemUid".
*/
public String getItemUid() {
return itemUid;
}

/**
* The function returns the content type UID as a string.
*
* @return The method is returning the value of the variable "contentTypeUid".
*/
public String getContentTypeUid() {
return contentTypeUid;
}

/**
* The function returns the value of the styleType variable.
*
* @return The method is returning the value of the variable "styleType" of type StyleType.
*/
public StyleType getStyleType() {
return styleType;
}

/**
* The getOuterHTML() function returns the outer HTML of an element.
*
* @return The method is returning the value of the variable "outerHTML".
*/
public String getOuterHTML() {
return outerHTML;
}
}

enum StyleType {
BLOCK, INLINE, LINK, DISPLAY, DOWNLOAD,
}
Loading

1 comment on commit 81a8f32

@ishaileshmishra
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to keep the RTE in the different package @reeshika-h @abhinav-from-contentstack

Please sign in to comment.