Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

back merge to next #59

Merged
merged 4 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading