From 516b7941a788490e857ef872980e30c28724fd28 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 21 Dec 2022 14:07:02 +0100 Subject: [PATCH 001/136] update gradle, SDK 33 --- build.gradle | 2 +- gradle.properties | 8 ++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- richeditor/build.gradle | 2 -- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index d8af90f..b27694b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.0-beta04' + classpath 'com.android.tools.build:gradle:7.3.1' // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' diff --git a/gradle.properties b/gradle.properties index 145e04c..c5cf844 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ org.gradle.parallel=true org.gradle.daemon=true org.gradle.configureondemand=true org.gradle.caching=true -android.enableBuildCache=true +#android.enableBuildCache=true android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true @@ -23,7 +23,7 @@ VERSION_NAME=2.0.0 VERSION_CODE=200 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android -COMPILE_SDK_VERSION=30 -TARGET_SDK_VERSION=30 -MIN_SDK_VERSION=14 +COMPILE_SDK_VERSION=33 +TARGET_SDK_VERSION=33 +MIN_SDK_VERSION=26 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5a491c5..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/richeditor/build.gradle b/richeditor/build.gradle index 1232748..4c76ccb 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -6,8 +6,6 @@ android { defaultConfig { minSdkVersion MIN_SDK_VERSION as int targetSdkVersion TARGET_SDK_VERSION as int - versionCode VERSION_CODE as int - versionName VERSION_NAME } } From ec9e39bcbb27d377d3721a056575727358a6c836 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:41:50 +0100 Subject: [PATCH 002/136] update gradle, SDK 30 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c5cf844..6b00a86 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,6 +24,6 @@ VERSION_CODE=200 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=33 -TARGET_SDK_VERSION=33 -MIN_SDK_VERSION=26 +TARGET_SDK_VERSION=30 +MIN_SDK_VERSION=24 From dfa8b9142dea3b18b8851c39045638688bfa040e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:45:21 +0100 Subject: [PATCH 003/136] merge HTML & css files --- richeditor/src/main/assets/assert.js | 27 + richeditor/src/main/assets/editor.html | 13 - richeditor/src/main/assets/normalize.css | 138 ++-- richeditor/src/main/assets/rich_editor.js | 596 +++++++++++------- .../src/main/assets/rich_editor_tests.html | 15 + .../src/main/assets/rich_editor_tests.js | 72 +++ richeditor/src/main/assets/style.css | 71 ++- 7 files changed, 607 insertions(+), 325 deletions(-) create mode 100644 richeditor/src/main/assets/assert.js delete mode 100644 richeditor/src/main/assets/editor.html create mode 100644 richeditor/src/main/assets/rich_editor_tests.html create mode 100644 richeditor/src/main/assets/rich_editor_tests.js diff --git a/richeditor/src/main/assets/assert.js b/richeditor/src/main/assets/assert.js new file mode 100644 index 0000000..f4af7f0 --- /dev/null +++ b/richeditor/src/main/assets/assert.js @@ -0,0 +1,27 @@ +//worlds smallest unit testing framework +var Assert = (Assert = function() { + var AssertException = function(message) { + this.message = message; + }; + + AssertException.prototype.toString = function() { + return 'AssertException: ' + this.message; + }; + + this.assert = this.that = function(exp, message) { + + if (!exp) { + throw new AssertException(message); + } + } + + this.equals = function(expected, actual, detail) { + this.assert(expected == actual, 'Failed asserting that ' + expected + '===' + actual + ' :: ' + detail); + } + + this.type = function(expectedType, actual) { + this.assert(expectedType === actual.constructor.name, 'Failed asserting that types match: ' + expectedType + ' === ' + actual.constructor.name); + } + //end worlds smallest unit testing framework + return this; +}()); \ No newline at end of file diff --git a/richeditor/src/main/assets/editor.html b/richeditor/src/main/assets/editor.html deleted file mode 100644 index 5357fe3..0000000 --- a/richeditor/src/main/assets/editor.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - -
- - - diff --git a/richeditor/src/main/assets/normalize.css b/richeditor/src/main/assets/normalize.css index 192eb9c..c2cff88 100644 --- a/richeditor/src/main/assets/normalize.css +++ b/richeditor/src/main/assets/normalize.css @@ -1,7 +1,7 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ + ========================================================================== */ /** * 1. Correct the line height in all browsers. @@ -9,27 +9,19 @@ */ html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections - ========================================================================== */ + ========================================================================== */ /** * Remove the margin in all browsers. */ body { - margin: 0; -} - -/** - * Render the `main` element consistently in IE. - */ - -main { - display: block; + margin: 0; } /** @@ -38,12 +30,12 @@ main { */ h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } /* Grouping content - ========================================================================== */ + ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. @@ -51,9 +43,9 @@ h1 { */ hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } /** @@ -62,19 +54,19 @@ hr { */ pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /* Text-level semantics - ========================================================================== */ + ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { - background-color: transparent; + background-color: transparent; } /** @@ -83,9 +75,9 @@ a { */ abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /** @@ -94,7 +86,7 @@ abbr[title] { b, strong { - font-weight: bolder; + font-weight: bolder; } /** @@ -105,8 +97,8 @@ strong { code, kbd, samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** @@ -114,7 +106,7 @@ samp { */ small { - font-size: 80%; + font-size: 80%; } /** @@ -124,33 +116,33 @@ small { sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } /* Embedded content - ========================================================================== */ + ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { - border-style: none; + border-style: none; } /* Forms - ========================================================================== */ + ========================================================================== */ /** * 1. Change the font styles in all browsers. @@ -162,10 +154,10 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** @@ -175,7 +167,7 @@ textarea { button, input { /* 1 */ - overflow: visible; + overflow: visible; } /** @@ -185,7 +177,7 @@ input { /* 1 */ button, select { /* 1 */ - text-transform: none; + text-transform: none; } /** @@ -196,7 +188,7 @@ button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } /** @@ -207,8 +199,8 @@ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; + border-style: none; + padding: 0; } /** @@ -219,7 +211,7 @@ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } /** @@ -227,7 +219,7 @@ button:-moz-focusring, */ fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } /** @@ -238,12 +230,12 @@ fieldset { */ legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } /** @@ -251,7 +243,7 @@ legend { */ progress { - vertical-align: baseline; + vertical-align: baseline; } /** @@ -259,7 +251,7 @@ progress { */ textarea { - overflow: auto; + overflow: auto; } /** @@ -269,8 +261,8 @@ textarea { [type="checkbox"], [type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } /** @@ -279,7 +271,7 @@ textarea { [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } /** @@ -288,8 +280,8 @@ textarea { */ [type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** @@ -297,7 +289,7 @@ textarea { */ [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } /** @@ -306,19 +298,19 @@ textarea { */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } /* Interactive - ========================================================================== */ + ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { - display: block; + display: block; } /* @@ -326,18 +318,18 @@ details { */ summary { - display: list-item; + display: list-item; } /* Misc - ========================================================================== */ + ========================================================================== */ /** * Add the correct display in IE 10+. */ template { - display: none; + display: none; } /** @@ -345,5 +337,5 @@ template { */ [hidden] { - display: none; + display: none; } diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index cf45620..334ec84 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2020 Wasabeef + * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,324 +13,331 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * See about document.execCommand: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand - */ + "use strict"; var RE = {}; -RE.currentSelection = { - "startContainer": 0, - "startOffset": 0, - "endContainer": 0, - "endOffset": 0}; - RE.editor = document.getElementById('editor'); -document.addEventListener("selectionchange", function() { RE.backuprange(); }); +// Not universally supported, but seems to work in iOS 7 and 8 +document.addEventListener("selectionchange", function() { + RE.backuprange(); +}); + +//looks specifically for a Range selection and not a Caret selection +RE.rangeSelectionExists = function() { + //!! coerces a null to bool + var sel = document.getSelection(); + if (sel && sel.type == "Range") { + return true; + } + return false; +}; + +RE.rangeOrCaretSelectionExists = function() { + //!! coerces a null to bool + var sel = document.getSelection(); + if (sel && (sel.type == "Range" || sel.type == "Caret")) { + return true; + } + return false; +}; + +// Returns selected text range +RE.selectedText = function() { + if (RE.rangeSelectionExists() == true) { + return document.getSelection().toString(); + } + return ""; +}; + +RE.editor.addEventListener("input", function() { + RE.updatePlaceholder(); + RE.backuprange(); + RE.callback("input"); +}); + +RE.editor.addEventListener("focus", function() { + RE.backuprange(); + RE.callback("focus"); +}); + +RE.editor.addEventListener("blur", function() { + RE.callback("blur"); +}); + +RE.customAction = function(action) { + RE.callback("action/" + action); +}; -// Initializations -RE.callback = function() { - window.location.href = "re-callback://" + encodeURIComponent(RE.getHtml()); +RE.updateHeight = function() { + RE.callback("updateHeight"); } +RE.callbackQueue = []; +RE.runCallbackQueue = function() { + if (RE.callbackQueue.length === 0) { + return; + } + + setTimeout(function() { + window.location.href = "re-callback://"; + }, 0); +}; + +RE.getCommandQueue = function() { + var commands = JSON.stringify(RE.callbackQueue); + RE.callbackQueue = []; + return commands; +}; + +RE.callback = function(method) { + RE.callbackQueue.push(method); + RE.runCallbackQueue(); +}; + RE.setHtml = function(contents) { - RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20')); -} + var tempWrapper = document.createElement('div'); + tempWrapper.innerHTML = contents; + var images = tempWrapper.querySelectorAll("img"); + + for (var i = 0; i < images.length; i++) { + images[i].onload = RE.updateHeight; + } + + RE.editor.innerHTML = tempWrapper.innerHTML; + RE.updatePlaceholder(); +}; RE.getHtml = function() { return RE.editor.innerHTML; -} +}; RE.getText = function() { return RE.editor.innerText; -} +}; RE.setBaseTextColor = function(color) { RE.editor.style.color = color; -} +}; -RE.setBaseFontSize = function(size) { - RE.editor.style.fontSize = size; -} +RE.setPlaceholderText = function(text) { + RE.editor.setAttribute("placeholder", text); +}; -RE.setPadding = function(left, top, right, bottom) { - RE.editor.style.paddingLeft = left; - RE.editor.style.paddingTop = top; - RE.editor.style.paddingRight = right; - RE.editor.style.paddingBottom = bottom; -} +RE.updatePlaceholder = function() { + if (RE.editor.innerHTML.indexOf('img') !== -1 || (RE.editor.textContent.length > 0 && RE.editor.innerHTML.length > 0)) { + RE.editor.classList.remove("placeholder"); + } else { + RE.editor.classList.add("placeholder"); + } +}; -RE.setBackgroundColor = function(color) { - document.body.style.backgroundColor = color; -} +RE.removeFormat = function() { + document.execCommand('removeFormat', false, null); +}; -RE.setBackgroundImage = function(image) { - RE.editor.style.backgroundImage = image; -} +RE.setFontSize = function(size) { + RE.editor.style.fontSize = size; +}; -RE.setWidth = function(size) { - RE.editor.style.minWidth = size; -} +RE.setBackgroundColor = function(color) { + RE.editor.style.backgroundColor = color; +}; RE.setHeight = function(size) { RE.editor.style.height = size; -} - -RE.setTextAlign = function(align) { - RE.editor.style.textAlign = align; -} - -RE.setVerticalAlign = function(align) { - RE.editor.style.verticalAlign = align; -} - -RE.setPlaceholder = function(placeholder) { - RE.editor.setAttribute("placeholder", placeholder); -} - -RE.setInputEnabled = function(inputEnabled) { - RE.editor.contentEditable = String(inputEnabled); -} +}; RE.undo = function() { document.execCommand('undo', false, null); -} +}; RE.redo = function() { document.execCommand('redo', false, null); -} +}; RE.setBold = function() { document.execCommand('bold', false, null); -} +}; RE.setItalic = function() { document.execCommand('italic', false, null); -} +}; RE.setSubscript = function() { document.execCommand('subscript', false, null); -} +}; RE.setSuperscript = function() { document.execCommand('superscript', false, null); -} +}; RE.setStrikeThrough = function() { document.execCommand('strikeThrough', false, null); -} +}; RE.setUnderline = function() { document.execCommand('underline', false, null); -} - -RE.setBullets = function() { - document.execCommand('insertUnorderedList', false, null); -} - -RE.setNumbers = function() { - document.execCommand('insertOrderedList', false, null); -} +}; RE.setTextColor = function(color) { RE.restorerange(); document.execCommand("styleWithCSS", null, true); document.execCommand('foreColor', false, color); document.execCommand("styleWithCSS", null, false); -} +}; RE.setTextBackgroundColor = function(color) { RE.restorerange(); document.execCommand("styleWithCSS", null, true); document.execCommand('hiliteColor', false, color); document.execCommand("styleWithCSS", null, false); -} - -RE.setFontSize = function(fontSize){ - document.execCommand("fontSize", false, fontSize); -} +}; RE.setHeading = function(heading) { - document.execCommand('formatBlock', false, ''); -} + var sel = document.getSelection().getRangeAt(0).startContainer.parentNode; + document.execCommand('formatBlock', false, sel.tagName === `H${heading}` ? '

' : ``); +}; RE.setIndent = function() { document.execCommand('indent', false, null); -} +}; RE.setOutdent = function() { document.execCommand('outdent', false, null); -} +}; + +RE.setOrderedList = function() { + document.execCommand('insertOrderedList', false, null); +}; + +RE.setUnorderedList = function() { + document.execCommand('insertUnorderedList', false, null); +}; + +function createCheckbox(id) { + var el = document.querySelector("input[name='" + id + "']"); + var d = document.createElement("input"); + d.setAttribute("type", "checkbox"); + d.setAttribute("name", id); + if(el.checked) { + d.setAttribute("checked", null); + } + el.parentNode.insertBefore(d, el); + el.parentNode.removeChild(el); + el = document.querySelector("input[name='" + id + "']"); + el.addEventListener("change", function() {createCheckbox(id);}); +}; + +RE.setCheckbox = function(id) { + var el = document.createElement("input"); + el.setAttribute("type", "checkbox"); + el.setAttribute("name", id); + RE.insertHTML(" " + el.outerHTML + " "); + el = document.querySelector("input[name='" + id + "']"); + el.addEventListener("change", function() {createCheckbox(id);}); + RE.callback("input"); +}; RE.setJustifyLeft = function() { document.execCommand('justifyLeft', false, null); -} +}; RE.setJustifyCenter = function() { document.execCommand('justifyCenter', false, null); -} +}; RE.setJustifyRight = function() { document.execCommand('justifyRight', false, null); -} +}; -RE.setBlockquote = function() { - document.execCommand('formatBlock', false, '

'); -} +RE.getLineHeight = function() { + return RE.editor.style.lineHeight; +}; -RE.insertImage = function(url, alt) { - var html = '' + alt + ''; - RE.insertHTML(html); -} - -RE.insertImageW = function(url, alt, width) { - var html = '' + alt + ''; - RE.insertHTML(html); -} - -RE.insertImageWH = function(url, alt, width, height) { - var html = '' + alt + ''; - RE.insertHTML(html); -} +RE.setLineHeight = function(height) { + RE.editor.style.lineHeight = height; +}; -RE.insertVideo = function(url, alt) { - var html = '
'; - RE.insertHTML(html); -} - -RE.insertVideoW = function(url, width) { - var html = '
'; - RE.insertHTML(html); -} - -RE.insertVideoWH = function(url, width, height) { - var html = '
'; - RE.insertHTML(html); -} - -RE.insertAudio = function(url, alt) { - var html = '
'; - RE.insertHTML(html); -} - -RE.insertYoutubeVideo = function(url) { - var html = '
' - RE.insertHTML(html); -} +RE.insertImage = function(url, alt) { + var img = document.createElement('img'); + img.setAttribute("src", url); + img.setAttribute("alt", alt); + img.onload = RE.updateHeight; -RE.insertYoutubeVideoW = function(url, width) { - var html = '
' - RE.insertHTML(html); -} + RE.insertHTML(img.outerHTML); + RE.callback("input"); +}; -RE.insertYoutubeVideoWH = function(url, width, height) { - var html = '
' - RE.insertHTML(html); -} +RE.setBlockquote = function() { + document.execCommand('formatBlock', false, '
'); +}; RE.insertHTML = function(html) { RE.restorerange(); document.execCommand('insertHTML', false, html); -} +}; -RE.insertLink = function(url, title) { +RE.insertLink = function(url, text, title) { RE.restorerange(); var sel = document.getSelection(); if (sel.toString().length == 0) { - document.execCommand("insertHTML",false,""+title+""); + document.execCommand("insertHTML",false,""+text+""); } else if (sel.rangeCount) { - var el = document.createElement("a"); - el.setAttribute("href", url); - el.setAttribute("title", title); - - var range = sel.getRangeAt(0).cloneRange(); - range.surroundContents(el); - sel.removeAllRanges(); - sel.addRange(range); - } + var el = document.createElement("a"); + el.setAttribute("href", url); + el.setAttribute("title", title); + + var range = sel.getRangeAt(0).cloneRange(); + range.surroundContents(el); + sel.removeAllRanges(); + sel.addRange(range); + } RE.callback(); -} - -RE.setTodo = function(text) { - var html = '  '; - document.execCommand('insertHTML', false, html); -} +}; RE.prepareInsert = function() { RE.backuprange(); -} +}; -RE.backuprange = function(){ +RE.backuprange = function() { var selection = window.getSelection(); if (selection.rangeCount > 0) { - var range = selection.getRangeAt(0); - RE.currentSelection = { - "startContainer": range.startContainer, - "startOffset": range.startOffset, - "endContainer": range.endContainer, - "endOffset": range.endOffset}; + var range = selection.getRangeAt(0); + RE.currentSelection = { + "startContainer": range.startContainer, + "startOffset": range.startOffset, + "endContainer": range.endContainer, + "endOffset": range.endOffset + }; } -} +}; + +RE.addRangeToSelection = function(selection, range) { + if (selection) { + selection.removeAllRanges(); + selection.addRange(range); + } +}; + +// Programatically select a DOM element +RE.selectElementContents = function(el) { + var range = document.createRange(); + range.selectNodeContents(el); + var sel = window.getSelection(); + // this.createSelectionFromRange sel, range + RE.addRangeToSelection(sel, range); +}; -RE.restorerange = function(){ +RE.restorerange = function() { var selection = window.getSelection(); selection.removeAllRanges(); var range = document.createRange(); range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset); range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset); selection.addRange(range); -} - -RE.enabledEditingItems = function(e) { - var items = []; - if (document.queryCommandState('bold')) { - items.push('bold'); - } - if (document.queryCommandState('italic')) { - items.push('italic'); - } - if (document.queryCommandState('subscript')) { - items.push('subscript'); - } - if (document.queryCommandState('superscript')) { - items.push('superscript'); - } - if (document.queryCommandState('strikeThrough')) { - items.push('strikeThrough'); - } - if (document.queryCommandState('underline')) { - items.push('underline'); - } - if (document.queryCommandState('insertOrderedList')) { - items.push('orderedList'); - } - if (document.queryCommandState('insertUnorderedList')) { - items.push('unorderedList'); - } - if (document.queryCommandState('justifyCenter')) { - items.push('justifyCenter'); - } - if (document.queryCommandState('justifyFull')) { - items.push('justifyFull'); - } - if (document.queryCommandState('justifyLeft')) { - items.push('justifyLeft'); - } - if (document.queryCommandState('justifyRight')) { - items.push('justifyRight'); - } - if (document.queryCommandState('insertHorizontalRule')) { - items.push('horizontalRule'); - } - var formatBlock = document.queryCommandValue('formatBlock'); - if (formatBlock.length > 0) { - items.push(formatBlock); - } - - window.location.href = "re-state://" + encodeURI(items.join(',')); -} +}; RE.focus = function() { var range = document.createRange(); @@ -340,22 +347,163 @@ RE.focus = function() { selection.removeAllRanges(); selection.addRange(range); RE.editor.focus(); -} +}; + +RE.focusAtPoint = function(x, y) { + var range = document.caretRangeFromPoint(x, y) || document.createRange(); + var selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + RE.editor.focus(); +}; RE.blurFocus = function() { RE.editor.blur(); -} +}; + +// User editing table functionality +RE.insertTable = function(width, height) { + var table = document.createElement("table"); + for (let i = 0; i < height; i++) { + var row = table.insertRow(); + for (let j = 0; j < width; j++) { + var cell = row.insertCell(); + } + } -RE.removeFormat = function() { - document.execCommand('removeFormat', false, null); -} + RE.insertHTML(table.outerHTML); + RE.callback("input"); +}; -// Event Listeners -RE.editor.addEventListener("input", RE.callback); -RE.editor.addEventListener("keyup", function(e) { - var KEY_LEFT = 37, KEY_RIGHT = 39; - if (e.which == KEY_LEFT || e.which == KEY_RIGHT) { - RE.enabledEditingItems(e); +function getNearestTableAncestor(htmlElementNode) { + while (htmlElementNode) { + htmlElementNode = htmlElementNode.parentNode; + if (htmlElementNode.tagName.toLowerCase() === 'table') { + return htmlElementNode; + } } -}); -RE.editor.addEventListener("click", RE.enabledEditingItems); + return undefined; +} + +RE.isCursorInTable = function() { + return document.querySelectorAll(":hover")[elements.length - 1] instanceof HTMLTableCellElement +}; + +RE.addRowToTable = function() { + // Add row below current cursor's + var elements = document.querySelectorAll(":hover"); + let rowIndex = elements[elements.length - 2].rowIndex; + let table = getNearestTableAncestor(elements[elements.length - 1]); + table.insertRow(rowIndex + 1); +}; + +RE.deleteRowFromTable = function() { + // Deletes the current cursor's row + var elements = document.querySelectorAll(":hover"); + let rowIndex = elements[elements.length - 2].rowIndex; + let table = getNearestTableAncestor(elements[elements.length - 1]); + table.deleteRow(rowIndex); +}; + +RE.addColumnToTable = function() { + // Add column to the right of current cursor's + var elements = document.querySelectorAll(":hover"); + let columnIndex = elements[elements.length - 1].cellIndex; + let row = elements[elements.length - 2]; + row.insertCell(columnIndex + 1); +} + +RE.deleteColumnFromTable = function() { + // Deletes the current cursor's column + var elements = document.querySelectorAll(":hover"); + let columnIndex = elements[elements.length - 1].cellIndex; + let row = elements[elements.length - 2]; + row.deleteCell(columnIndex); +}; + +/** +Recursively search element ancestors to find a element nodeName e.g. A +**/ +var _findNodeByNameInContainer = function(element, nodeName, rootElementId) { + if (element.nodeName == nodeName) { + return element; + } else { + if (element.id === rootElementId) { + return null; + } + _findNodeByNameInContainer(element.parentElement, nodeName, rootElementId); + } +}; + +var isAnchorNode = function(node) { + return ("A" == node.nodeName); +}; + +RE.getAnchorTagsInNode = function(node) { + var links = []; + + while (node.nextSibling !== null && node.nextSibling !== undefined) { + node = node.nextSibling; + if (isAnchorNode(node)) { + links.push(node.getAttribute('href')); + } + } + return links; +}; + +RE.countAnchorTagsInNode = function(node) { + return RE.getAnchorTagsInNode(node).length; +}; + +/** + * If the current selection's parent is an anchor tag, get the href. + * @returns {string} + */ +RE.getSelectedHref = function() { + var href, sel; + href = ''; + sel = window.getSelection(); + if (!RE.rangeOrCaretSelectionExists()) { + return null; + } + + var tags = RE.getAnchorTagsInNode(sel.anchorNode); + //if more than one link is there, return null + if (tags.length > 1) { + return null; + } else if (tags.length == 1) { + href = tags[0]; + } else { + var node = _findNodeByNameInContainer(sel.anchorNode.parentElement, 'A', 'editor'); + href = node.href; + } + return href ? href : null; +}; + +// Returns the cursor position relative to its current position onscreen. +// Can be negative if it is above what is visible +RE.getRelativeCaretYPosition = function() { + var y = 0; + var sel = window.getSelection(); + if (sel.rangeCount) { + var range = sel.getRangeAt(0); + var needsWorkAround = (range.startOffset == 0) + /* Removing fixes bug when node name other than 'div' */ + // && range.startContainer.nodeName.toLowerCase() == 'div'); + if (needsWorkAround) { + y = range.startContainer.offsetTop - window.pageYOffset; + } else { + if (range.getClientRects) { + var rects = range.getClientRects(); + if (rects.length > 0) { + y = rects[0].top; + } + } + } + } + return y; +}; + +window.onload = function() { + RE.callback("ready"); +}; diff --git a/richeditor/src/main/assets/rich_editor_tests.html b/richeditor/src/main/assets/rich_editor_tests.html new file mode 100644 index 0000000..c12f3ec --- /dev/null +++ b/richeditor/src/main/assets/rich_editor_tests.html @@ -0,0 +1,15 @@ + + + + + + + + +
+
+ + + + + diff --git a/richeditor/src/main/assets/rich_editor_tests.js b/richeditor/src/main/assets/rich_editor_tests.js new file mode 100644 index 0000000..9849431 --- /dev/null +++ b/richeditor/src/main/assets/rich_editor_tests.js @@ -0,0 +1,72 @@ +"use strict"; + +var RichEditorTests = function() { + var self = {}; + var tests = []; + var link = "http://foo.bar/"; + var anchor = "Foo"; + var htmlWithLink = "

What are these so withered and wild in their attire? " + anchor + "

that look not like the inhabitants of the Earth and yet are on't?
"; + var htmlWith2Links = ""; + + var tearDown = function() { + RE.setHtml(''); + }; + + /** + This is the main and only public "method" + **/ + self.runTests = function() { + var content = ""; + for (var testName in tests) { + tests[testName](); + var log = 'Passed : ' + testName; + console.log(log); + content += log + "
"; + tearDown(); + } + RE.setHtml(content); + }; + + tests['testGetSet'] = function() { + var testContent = "Test"; + RE.setHtml(testContent); + Assert.equals(RE.getHtml(), testContent, 'testGetSet'); + }; + + tests['testGetSelectedHrefReturnsLinkOnFullSelection'] = function() { + let htmlWithLink = "Foo"; + RE.setHtml(htmlWithLink); + //select the anchor tag directly and fully + RE.selectElementContents(document.querySelector('#link_id')); + Assert.equals(RE.getSelectedHref(), link); + }; + + tests['testGetSelectedHrefWithSelectionContainingOneLink'] = function() { + RE.setHtml(htmlWithLink); + //select the anchor tag directly and fully + RE.selectElementContents(document.querySelector('#prose')); + Assert.equals(RE.getSelectedHref(), link); + }; + + tests['testCountAnchorTagsInSelection'] = function() { + RE.setHtml(htmlWithLink); + //select the anchor tag directly and fully + RE.selectElementContents(document.querySelector('#prose')); + let count = RE.countAnchorTagsInNode(getSelection().anchorNode); + Assert.equals(count, 1); + }; + + tests['testgetSelectedHrefWith2LinksReturnsNull'] = function() { + RE.setHtml(htmlWith2Links); + + //select the anchor tag directly and fully + RE.selectElementContents(document.querySelector('#two_links')); + let count = RE.countAnchorTagsInNode(getSelection().anchorNode); + Assert.equals(count, 2); + // Assert.equals(RE.getSelectedHref(), null) + }; + + return self; +}(); + +RichEditorTests.runTests(); \ No newline at end of file diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index 89772a6..e5dae6f 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -1,5 +1,5 @@ /** - * Copyright (C) 2020 Wasabeef + * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,69 @@ @charset "UTF-8"; +:root { + color-scheme: light dark; +} html { - height: 100%; + height: 100%; } body { - overflow: scroll; - display: table; - table-layout: fixed; - width: 100%; - min-height:100%; + min-height: 100%; + overflow: auto; + font: -apple-system-body; +} + +body, h1, p, ul, ol { + margin: 0; +} + +div { + display: block; + position: static; } #editor { - display: table-cell; - outline: 0px solid transparent; - background-repeat: no-repeat; - background-position: center; - background-size: cover; + -webkit-user-select: auto !important; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +#editor:focus { + outline: 0px solid transparent; +} + +@media (prefers-color-scheme: dark) { + body, #editor { + } } -#editor[placeholder]:empty:not(:focus):before { - content: attr(placeholder); - opacity: .5; +.placeholder[placeholder]:after { + content: attr(placeholder); + position: absolute; + top: 0px; + color: #cccccc; } + +#editor { + min-height: 100%; + height: 100%; + overflow: auto; + display: block; + font-size: 12pt; +} + +input[type=checkbox] { + transform: scale(1.4); + margin-right: 9px; +} + +video { + width: 100% !important; + height: auto !important; +} + +table {overflow-x: scroll;} +th, td {max-width: 200px; min-width:50px;} +table, td, th{border-collapse:collapse; border:1px solid #777;} +td{padding:5px 10px; height:35px;} From 519652841c04eee29e2843233e4dd4ae3636098f Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:45:55 +0100 Subject: [PATCH 004/136] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7760395..69ed818 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@

+This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) + `RichEditor for Android` is a beautiful Rich Text `WYSIWYG Editor` for `Android`. - _Looking for iOS? Check out_ [cjwirth/RichEditorView](https://github.com/cjwirth/RichEditorView) From 9275f8b9e1d2c895aaf1bd243f2828076ea831de Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:46:09 +0100 Subject: [PATCH 005/136] update Project.xml --- .idea/codeStyles/Project.xml | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 638fb6b..52792e7 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,7 +1,5 @@ - - - - + \ No newline at end of file From 07266bd5cac8afe214dfac4ada9b4cb8ac0f4727 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:46:41 +0100 Subject: [PATCH 006/136] merge HTML & CSS files --- richeditor/src/main/assets/rich_editor.html | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 richeditor/src/main/assets/rich_editor.html diff --git a/richeditor/src/main/assets/rich_editor.html b/richeditor/src/main/assets/rich_editor.html new file mode 100644 index 0000000..3bfcb59 --- /dev/null +++ b/richeditor/src/main/assets/rich_editor.html @@ -0,0 +1,17 @@ + + + + + + + + + + + +
+
+
+ + + From 831644fb09ae85aaabfcc4486d2151880772b23e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:51:39 +0100 Subject: [PATCH 007/136] add support to receive data from JS via callbacks --- .../jp/wasabeef/richeditor/RichEditor.java | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index d05481d..8475c34 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -12,6 +12,7 @@ import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; +import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebView; @@ -22,8 +23,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.concurrent.atomic.AtomicBoolean; /** + * Copyright (C) 2020 niendo * Copyright (C) 2020 Wasabeef *

* Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,27 +42,17 @@ * limitations under the License. */ -public class RichEditor extends WebView { +public class RichEditor extends WebView implements ValueCallback { public enum Type { - BOLD, - ITALIC, - SUBSCRIPT, - SUPERSCRIPT, - STRIKETHROUGH, - UNDERLINE, - H1, - H2, - H3, - H4, - H5, - H6, - ORDEREDLIST, - UNORDEREDLIST, - JUSTIFYCENTER, - JUSTIFYFULL, - JUSTIFYLEFT, - JUSTIFYRIGHT + BOLD, ITALIC, SUBSCRIPT, SUPERSCRIPT, STRIKETHROUGH, UNDERLINE, H1, H2, H3, H4, H5, H6, ORDEREDLIST, UNORDEREDLIST, JUSTIFYCENTER, JUSTIFYFULL, JUSTIFYLEFT, JUSTIFYRIGHT + } + + private final AtomicBoolean mEvaluateFinished = new AtomicBoolean(false); + + public interface onJSDataListener { + public void onDataReceived(String value); + //public void onActionFailure(Throwable throwableError); } public interface OnTextChangeListener { @@ -77,12 +70,13 @@ public interface AfterInitialLoadListener { void onAfterInitialLoad(boolean isReady); } - private static final String SETUP_HTML = "file:///android_asset/editor.html"; + private static final String SETUP_HTML = "file:///android_asset/rich_editor.html"; private static final String CALLBACK_SCHEME = "re-callback://"; private static final String STATE_SCHEME = "re-state://"; private boolean isReady = false; private String mContents; private OnTextChangeListener mTextChangeListener; + private onJSDataListener mJSDataListener; private OnDecorationStateListener mDecorationStateListener; private AfterInitialLoadListener mLoadListener; @@ -116,6 +110,10 @@ public void setOnTextChangeListener(OnTextChangeListener listener) { mTextChangeListener = listener; } + public void setOnJSDataListener(onJSDataListener listener) { + mJSDataListener = listener; + } + public void setOnDecorationChangeListener(OnDecorationStateListener listener) { mDecorationStateListener = listener; } @@ -124,7 +122,23 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { mLoadListener = listener; } - private void callback(String text) { + @Override public void onReceiveValue(String value) { + + String unescaped=""; + if ("null".equals(value)) { + + } else { + unescaped = value.substring(1, value.length() - 1) // remove wrapping quotes + .replace("\\\\", "\\") // unescape \\ -> \ + .replace("\\\"", "\""); // unescape \" -> " + } + + if (mJSDataListener != null) { + mJSDataListener.onDataReceived(unescaped); + } + } + + private void callback(String text) { mContents = text.replaceFirst(CALLBACK_SCHEME, ""); if (mTextChangeListener != null) { mTextChangeListener.onTextChange(mContents); @@ -146,7 +160,7 @@ private void stateCheck(String text) { } private void applyAttributes(Context context, AttributeSet attrs) { - final int[] attrsArray = new int[]{ + final int[] attrsArray = new int[] { android.R.attr.gravity }; TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray); @@ -266,15 +280,11 @@ public void setInputEnabled(Boolean inputEnabled) { } public void loadCSS(String cssFile) { - String jsCSSImport = "(function() {" + - " var head = document.getElementsByTagName(\"head\")[0];" + - " var link = document.createElement(\"link\");" + - " link.rel = \"stylesheet\";" + - " link.type = \"text/css\";" + - " link.href = \"" + cssFile + "\";" + - " link.media = \"all\";" + - " head.appendChild(link);" + - "}) ();"; + String jsCSSImport = + "(function() {" + " var head = document.getElementsByTagName(\"head\")[0];" + + " var link = document.createElement(\"link\");" + " link.rel = \"stylesheet\";" + + " link.type = \"text/css\";" + " link.href = \"" + cssFile + "\";" + + " link.media = \"all\";" + " head.appendChild(link);" + "}) ();"; exec("javascript:" + jsCSSImport + ""); } @@ -465,9 +475,8 @@ protected void exec(final String trigger) { load(trigger); } else { postDelayed(new Runnable() { - @Override - public void run() { - exec(trigger); + @Override public void run() { + exec(trigger); } }, 100); } @@ -481,6 +490,14 @@ private void load(String trigger) { } } + public boolean requestJSData(String cmdJS) { + // https://stackoverflow.com/questions/38380246/espresso-how-to-call-evaluatejavascript-on-a-webview + mEvaluateFinished.set(false); + + evaluateJavascript(cmdJS, this); + return true; + } + protected class EditorWebViewClient extends WebViewClient { @Override public void onPageFinished(WebView view, String url) { From bde70c71e2bec99633e05e21902680307da5be55 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:53:15 +0100 Subject: [PATCH 008/136] add setText[Background]Color(String) --- README.md | 2 ++ .../java/jp/wasabeef/richeditor/RichEditor.java | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 69ed818..cc0f46c 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,9 @@ Supported Functions - [x] Insert Link - [x] Checkbox - [x] Text Color +- [x] (new) Text Color (String) - [x] Text Background Color +- [x] (new) Text Background Color (String) - [x] Text Font Size - [x] Unordered List (Bullets) - [x] Ordered List (Numbers) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 8475c34..0642a87 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -321,17 +321,22 @@ public void setUnderline() { } public void setTextColor(int color) { - exec("javascript:RE.prepareInsert();"); + setTextColor(convertHexColorString(color)); + } - String hex = convertHexColorString(color); - exec("javascript:RE.setTextColor('" + hex + "');"); + public void setTextColor(String color) { + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.setTextColor('" + color + "');"); } public void setTextBackgroundColor(int color) { - exec("javascript:RE.prepareInsert();"); - String hex = convertHexColorString(color); - exec("javascript:RE.setTextBackgroundColor('" + hex + "');"); + setTextBackgroundColor(convertHexColorString(color)); + } + + public void setTextBackgroundColor(String color) { + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.setTextBackgroundColor('" + color + "');"); } public void setFontSize(int fontSize) { From f9f8a0b79b236ed5b72e2ba593620248f24c56e2 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 13:55:52 +0100 Subject: [PATCH 009/136] add * getText * getSelectedText * getSelectedHref --- README.md | 2 ++ .../jp/wasabeef/richeditor/RichEditor.java | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/README.md b/README.md index cc0f46c..590a023 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ Supported Functions - [x] Text Font Size - [x] Unordered List (Bullets) - [x] Ordered List (Numbers) +- [x] (new) Get Selected Text +- [x] (new) Get Selected Href Attribute change of editor --- diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 0642a87..d465a5f 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -210,6 +210,36 @@ public String getHtml() { return mContents; } + /// Text representation of the data that has been input into the editor view, if it has been loaded. + public boolean getText() { + return requestJSData("RE.getText()"); + } + + /// Returns selected text + public boolean getSelectedText() { + return requestJSData("RE.selectedText()"); + } + + /// The href of the current selection, if the current selection's parent is an anchor tag. + /// Will be nil if there is no href, or it is an empty string. + public boolean getSelectedHref() { + if (!hasRangeSelection()) { + return false; + } else { + return requestJSData("RE.getSelectedHref()"); + } + } + + /// Whether or not the selection has a type specifically of "Range". + public boolean hasRangeSelection() { + return requestJSData("RE.rangeSelectionExists()"); + } + + /// Whether or not the selection has a type specifically of "Range" or "Caret". + public boolean hasRangeOrCaretSelection() { + return requestJSData("RE.rangeOrCaretSelectionExists()"); + } + public void setEditorFontColor(int color) { String hex = convertHexColorString(color); exec("javascript:RE.setBaseTextColor('" + hex + "');"); From 61ce991c689ee0ea30e2b3deaebc58049f2cb401 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 14:03:18 +0100 Subject: [PATCH 010/136] sample for getSelected text. If you select the word green, and click action_txt_color, the word is colored green. --- .../java/jp/wasabeef/sample/MainActivity.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 4bcf749..8d10498 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -141,8 +141,19 @@ public void onClick(View v) { @Override public void onClick(View v) { - mEditor.setTextColor(isChanged ? Color.BLACK : Color.RED); - isChanged = !isChanged; + // 1. get the selected text via callback + // 2. set the text color of the selection. the color is the selection it self + // so the selected text is for example 'green', the colored green + mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { + @Override public void onDataReceived(String value) { + if(!value.isEmpty()) + mEditor.setTextColor(value); + } + }); + + mEditor.getSelectedText(); + //mEditor.setTextColor(isChanged ? Color.BLACK : Color.RED); + //isChanged = !isChanged; } }); From 1a1d136f64a1fab65936f43772e03184a77763b6 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 14:03:42 +0100 Subject: [PATCH 011/136] new line missing --- .../androidTest/java/jp/wasabeef/sample/ApplicationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java b/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java index 5779d4a..946e30d 100644 --- a/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java +++ b/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java @@ -11,4 +11,4 @@ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } -} \ No newline at end of file +} From af4a2264546638fa785351145c79f73c9b5f4e57 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 14:05:51 +0100 Subject: [PATCH 012/136] add file runConfigurations.xml --- .idea/runConfigurations.xml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .idea/runConfigurations.xml diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 797acea..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file From 3239077b62523d99a7b4dd0e019621569e8fc9cf Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 23 Dec 2022 14:27:11 +0100 Subject: [PATCH 013/136] add * insert HTML * insert Horizontal Line --- README.md | 2 ++ .../jp/wasabeef/richeditor/RichEditor.java | 13 +++++++++++- .../java/jp/wasabeef/sample/MainActivity.java | 20 +++++++++++++++++++ sample/src/main/res/layout/activity_main.xml | 16 +++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 590a023..53d2612 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ Supported Functions - [x] Redo - [x] Indent - [x] Outdent +- [x] (new) Insert HTML Code +- [x] (new) Insert Horizontal Line - [x] Insert Image - [x] Insert Youtube - [x] Insert Video diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index d465a5f..3614cf8 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -45,7 +45,7 @@ public class RichEditor extends WebView implements ValueCallback { public enum Type { - BOLD, ITALIC, SUBSCRIPT, SUPERSCRIPT, STRIKETHROUGH, UNDERLINE, H1, H2, H3, H4, H5, H6, ORDEREDLIST, UNORDEREDLIST, JUSTIFYCENTER, JUSTIFYFULL, JUSTIFYLEFT, JUSTIFYRIGHT + BOLD, ITALIC, SUBSCRIPT, SUPERSCRIPT, STRIKETHROUGH, UNDERLINE, H1, H2, H3, H4, H5, H6, HTML, HR, ORDEREDLIST, UNORDEREDLIST, JUSTIFYCENTER, JUSTIFYFULL, JUSTIFYLEFT, JUSTIFYRIGHT } private final AtomicBoolean mEvaluateFinished = new AtomicBoolean(false); @@ -416,6 +416,17 @@ public void setNumbers() { exec("javascript:RE.setNumbers();"); } + public void insertHTML(String text) { + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertHTML('" + text + "')"); + } + + public void insertHR_Line() { + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertHTML('


')"); + } + + public void insertImage(String url, String alt) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertImage('" + url + "', '" + alt + "');"); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 8d10498..bebc2d0 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -14,6 +14,12 @@ public class MainActivity extends AppCompatActivity { private RichEditor mEditor; private TextView mPreview; + public boolean onReceiveValue(String value) { + String test = value; + test=test+" "; + return true; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -223,6 +229,20 @@ public void onClick(View v) { } }); + findViewById(R.id.action_insert_html).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.insertHTML("⭐"); + } + }); + + findViewById(R.id.action_insert_hrline).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.insertHR_Line(); + } + }); + findViewById(R.id.action_insert_image).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index 45d26f7..8d53cac 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -206,6 +206,22 @@ android:contentDescription="@null" android:src="@drawable/blockquote" /> + + + + Date: Sat, 24 Dec 2022 18:25:13 +0100 Subject: [PATCH 014/136] add * focus (X,Y) --- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 3614cf8..392279a 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -508,6 +508,11 @@ public void focusEditor() { exec("javascript:RE.focus();"); } + public void focus(Integer x, Integer y) { + requestFocus(); + exec("javascript:RE.focusAtPoint("+ x.toString() + ", "+ y.toString() + ")"); + } + public void clearFocusEditor() { exec("javascript:RE.blurFocus();"); } From 2897d923caf31a1dffe748ef8b1aa413b1e39fda Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 24 Dec 2022 18:38:22 +0100 Subject: [PATCH 015/136] replace TodDo with checkbox, that is actually saved --- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 8 ++++++-- sample/src/main/java/jp/wasabeef/sample/MainActivity.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 392279a..126c643 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -498,9 +499,12 @@ public void insertLink(String href, String title) { exec("javascript:RE.insertLink('" + href + "', '" + title + "');"); } - public void insertTodo() { + public String insertCheckbox(String uuid) { + if (uuid.isEmpty()) + uuid = UUID.randomUUID().toString();; exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.setTodo('" + Utils.getCurrentTime() + "');"); + exec("javascript:RE.setCheckbox('"+ uuid +"')"); + return uuid; } public void focusEditor() { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index bebc2d0..3528403 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -281,7 +281,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_checkbox).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertTodo(); + mEditor.insertCheckbox(""); } }); } From d8fde41dc246dd7e839347cd753e314b7de8c6fc Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 24 Dec 2022 18:46:43 +0100 Subject: [PATCH 016/136] fix some missing js --- richeditor/src/main/assets/rich_editor.js | 11 +++++++++++ .../main/java/jp/wasabeef/richeditor/RichEditor.java | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 334ec84..588ec11 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -121,6 +121,17 @@ RE.setBaseTextColor = function(color) { RE.editor.style.color = color; }; +RE.setBaseFontSize = function(size) { + RE.editor.style.fontSize = size; +} + +RE.setPadding = function(left, top, right, bottom) { + RE.editor.style.paddingLeft = left; + RE.editor.style.paddingTop = top; + RE.editor.style.paddingRight = right; + RE.editor.style.paddingBottom = bottom; +} + RE.setPlaceholderText = function(text) { RE.editor.setAttribute("placeholder", text); }; diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 126c643..ded5769 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -303,7 +303,7 @@ public void setEditorHeight(int px) { } public void setPlaceholder(String placeholder) { - exec("javascript:RE.setPlaceholder('" + placeholder + "');"); + exec("javascript:RE.setPlaceholderText('" + placeholder + "');"); } public void setInputEnabled(Boolean inputEnabled) { From 0f9d19b7858bc9293596612129d4a053cc66c0a4 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 24 Dec 2022 18:48:14 +0100 Subject: [PATCH 017/136] add missing icons * insert HTML * insert Horizontal Line --- .../main/res/drawable-xxhdpi/insert_hline.png | Bin 0 -> 258 bytes .../src/main/res/drawable-xxhdpi/insert_html.png | Bin 0 -> 1241 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_hline.png create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_html.png diff --git a/sample/src/main/res/drawable-xxhdpi/insert_hline.png b/sample/src/main/res/drawable-xxhdpi/insert_hline.png new file mode 100644 index 0000000000000000000000000000000000000000..dcd00645942ef8a90802564864b3217cafe93241 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=EX7WqAsj$Z!;#Vf%(ecmhgn+)D!=vD^L5j&FjE3KkL8?X-;f^_v`gPdLkes2-E`sdz$6c zgS^c87O#07rF`DM;(e+F+sohoO7<6i?Zz6`J2_R`}C$8Hs?3JuihEb qx^h)Xthypg;kmu<6PaOlGc+vb|KOzZDZOMO*g>AIelF{r5}E)x2ww*P literal 0 HcmV?d00001 diff --git a/sample/src/main/res/drawable-xxhdpi/insert_html.png b/sample/src/main/res/drawable-xxhdpi/insert_html.png new file mode 100644 index 0000000000000000000000000000000000000000..965efbe93eb8fff1a8225ea9067709d112855d14 GIT binary patch literal 1241 zcmV;~1Sb25P)x?Uz+yv9<~ebqEW3jL^PW6Xt9C@URwPG5=n_(7ss_g{h!0h=>Q4{X+YX zT9`Y~g*gi%;=ZLvX#Y_O_bgi6KY*y1GaH4@5wURBY{xw_qT;T(OXwUCiHvJ-rv|KW zyUHMRp0I^mRd(F221|4cohK~e&&m&}0I*BtCqm~6NeGxe#vhgc5MY%+n8y#bfw%+KmhF>H269;+m<7!S%yWmMbu+ z!@luu5Z8FhR+y~oe-3y` zzo!L=Z%V)0_$Cb{HveP!Wg;Mhcwt7T(E9_+SZi`hX*U5X1Qp zIincNew)?s!4e#*?QrC};mCtHVZ5ofa}qvS!a!~&hI0PJP%gv;dFs#0;52-&g#PSS z4CFvmkSAWk|6jlf0wUuCe+B%Wb&Pc;u{rXXa!l$sj_+ zi&jNrq?fi)2{mYyxx$$DCEIz|nmQwS4K32MWDFb9BAZ34^dmN&4Kzt!Mziz-I_As^ zX0|Zi*vR-|Q%niX$){mUULY*IC>NoF#a&D-3crCG2gRm1j9ks!eniX;68M-82!H!(Zj00000NkvXXu0mjf DfWuEq literal 0 HcmV?d00001 From 1c9dac0d62ad340fdd644dec869112c00af2789a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 24 Dec 2022 21:01:13 +0100 Subject: [PATCH 018/136] add table support --- README.md | 1 + richeditor/src/main/assets/rich_editor.js | 10 ++++- .../jp/wasabeef/richeditor/RichEditor.java | 27 ++++++++++++ .../java/jp/wasabeef/sample/MainActivity.java | 34 +++++++++++++++ .../res/drawable-xxhdpi/delete_column.png | Bin 0 -> 279 bytes .../main/res/drawable-xxhdpi/delete_row.png | Bin 0 -> 270 bytes .../res/drawable-xxhdpi/insert_column.png | Bin 0 -> 455 bytes .../main/res/drawable-xxhdpi/insert_row.png | Bin 0 -> 283 bytes .../res/drawable-xxhdpi/insert_table_2x2.png | Bin 0 -> 247 bytes sample/src/main/res/layout/activity_main.xml | 40 ++++++++++++++++++ 10 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/delete_column.png create mode 100644 sample/src/main/res/drawable-xxhdpi/delete_row.png create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_column.png create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_row.png create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_table_2x2.png diff --git a/README.md b/README.md index 53d2612..e1c9e08 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Supported Functions - [x] Ordered List (Numbers) - [x] (new) Get Selected Text - [x] (new) Get Selected Href +- [x] (new) Insert Table Attribute change of editor --- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 588ec11..0afe154 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,4 +1,5 @@ /** + * Copyright (C) 2022 niendo * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -404,8 +405,15 @@ RE.addRowToTable = function() { // Add row below current cursor's var elements = document.querySelectorAll(":hover"); let rowIndex = elements[elements.length - 2].rowIndex; + let columnIndex = elements[elements.length - 1].cellIndex; let table = getNearestTableAncestor(elements[elements.length - 1]); - table.insertRow(rowIndex + 1); + var row = table.insertRow(rowIndex + 1); + for (let j = 0; j < columnIndex + 1; j++) { + var cell = row.insertCell(); + } + // this is not working: + // table.insertRow(rowIndex + 1); + // and table.length also doesn't.. }; RE.deleteRowFromTable = function() { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index ded5769..f3067a7 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -537,6 +537,33 @@ protected void exec(final String trigger) { } } + // MARK: Table functionalities + public void insertTable(Integer col, Integer row) { + exec("javascript:RE.prepareInsert()"); + exec("javascript:RE.insertTable("+ col.toString() + "," + row.toString() + ")"); + } + + /// Checks if cursor is in a table element. If so, return true so that you can add menu items accordingly. + public void isCursorInTable() { + requestJSData("javascript:RE.isCursorInTable"); + } + + public void addRowToTable() { + exec("javascript:RE.addRowToTable()"); + } + + public void deleteRowFromTable() { + exec("javascript:RE.deleteRowFromTable()"); + } + + public void addColumnToTable() { + exec("javascript:RE.addColumnToTable()"); + } + + public void deleteColumnFromTable() { + exec("javascript:RE.deleteColumnFromTable()"); + } + private void load(String trigger) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { evaluateJavascript(trigger, null); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 3528403..63f8778 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -278,11 +278,45 @@ public void onClick(View v) { mEditor.insertLink("https://github.com/wasabeef", "wasabeef"); } }); + findViewById(R.id.action_insert_checkbox).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mEditor.insertCheckbox(""); } }); + + findViewById(R.id.action_insert_table_2x2).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { mEditor.insertTable(2,2); + } + }); + + findViewById(R.id.action_insert_row).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.addRowToTable(); + } + }); + + findViewById(R.id.action_insert_column).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { mEditor.addColumnToTable(); + } + }); + + findViewById(R.id.action_delete_row).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.deleteRowFromTable(); + } + }); + + findViewById(R.id.action_delete_column).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.deleteColumnFromTable(); + } + }); } } diff --git a/sample/src/main/res/drawable-xxhdpi/delete_column.png b/sample/src/main/res/drawable-xxhdpi/delete_column.png new file mode 100644 index 0000000000000000000000000000000000000000..79d7cd49c455ba61bf7720c4664f8130009fc3a7 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#VfxHCC$U zqwce?Ha0mp!ljtdx$lz>!j*i`6MH=yw^Fb{4`Ov@z?JB)f22~`nfD&#VFpiEKbLh* G2~7ZF>sk>2 literal 0 HcmV?d00001 diff --git a/sample/src/main/res/drawable-xxhdpi/delete_row.png b/sample/src/main/res/drawable-xxhdpi/delete_row.png new file mode 100644 index 0000000000000000000000000000000000000000..79ef9da828ba75a07e02dbaaf32f4fb05899f390 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#Vfu`v$aJ@U)#0fLKfb|c*N{NrE Qe>%vWp00i_>zopr0Ff(MEdT%j literal 0 HcmV?d00001 diff --git a/sample/src/main/res/drawable-xxhdpi/insert_column.png b/sample/src/main/res/drawable-xxhdpi/insert_column.png new file mode 100644 index 0000000000000000000000000000000000000000..49353f2d1c3ae48cde349c3c0c8e122f74d2996d GIT binary patch literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#X#z`$7N>Eakt zG3V_~L;ph#630G1H@#bM;o^)8nLq#JkDWYn#8sW0?WV#$K2g(SyVb8TRek@jsxu|~ zmi=+j6;~S1>^b{BcK1g2-xde#6Etl07cy7#mrS1dd~4%g_9&04mAr3kC#2Y=ZEgJT zmll^fM{u@&|H;OrZHuipoT-^sVw3nH=u%Yj3gg-=A;F86cxF}UE#KO!yVlXVax-Vj z7Lg3~sHo<5DzRBHDbANBANwq=GWSnGJb(VPshiMRreTmpl3K z7cTK=t*m43>PXEk;LpDBM88w0kz+~G0(Z|p@<6K8Ws2DQ^3Cx_jf|h)d#?D^pt-Kq zfvu5;Ns`6r+qYn4rL>(%)7DMeeaqhXgu(RKbLh*2~7Zlva})q literal 0 HcmV?d00001 diff --git a/sample/src/main/res/drawable-xxhdpi/insert_row.png b/sample/src/main/res/drawable-xxhdpi/insert_row.png new file mode 100644 index 0000000000000000000000000000000000000000..8165061d72b33fba08597547c1d89c8e5ef4cdfa GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#Vf|g@A~Cr3)+PmESbHUUqWvHFHOhn1BX{2n!bzD^v**_u$S51E`WUa=&G2_k7Zy z(|z=p+{O)-7q0Fr?&1XLI`rwJ^;5t33~DfA4sF`@dC#r8>vlx1H3aLvA@joT{rpTL q$CuglBK`mRORoG<)3Au-h3N2qC25fq{qbQX$lac6S3j3^P6 + + + + + + + + + + From 66acd6b9a5336c1de78ee722663e9a3b4887b454 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 26 Dec 2022 12:24:18 +0100 Subject: [PATCH 019/136] improve table support --- richeditor/src/main/assets/rich_editor.js | 11 ++++------- .../main/res/drawable-xxhdpi/delete_column.png | Bin 279 -> 7622 bytes .../main/res/drawable-xxhdpi/delete_row.png | Bin 270 -> 7627 bytes .../main/res/drawable-xxhdpi/insert_column.png | Bin 455 -> 8354 bytes .../main/res/drawable-xxhdpi/insert_row.png | Bin 283 -> 7639 bytes .../res/drawable-xxhdpi/insert_table_2x2.png | Bin 247 -> 6422 bytes 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 0afe154..7bd94ae 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -405,15 +405,12 @@ RE.addRowToTable = function() { // Add row below current cursor's var elements = document.querySelectorAll(":hover"); let rowIndex = elements[elements.length - 2].rowIndex; - let columnIndex = elements[elements.length - 1].cellIndex; let table = getNearestTableAncestor(elements[elements.length - 1]); + let columns = table.rows[rowIndex].cells.length; var row = table.insertRow(rowIndex + 1); - for (let j = 0; j < columnIndex + 1; j++) { - var cell = row.insertCell(); - } - // this is not working: - // table.insertRow(rowIndex + 1); - // and table.length also doesn't.. + for (let j = 0; j < columns ; j++) { + var cell = row.insertCell(); + } }; RE.deleteRowFromTable = function() { diff --git a/sample/src/main/res/drawable-xxhdpi/delete_column.png b/sample/src/main/res/drawable-xxhdpi/delete_column.png index 79d7cd49c455ba61bf7720c4664f8130009fc3a7..06c54f93516930eed9bcc15e93629d60dc18f508 100644 GIT binary patch literal 7622 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 G2~7ZF>sk>2 diff --git a/sample/src/main/res/drawable-xxhdpi/delete_row.png b/sample/src/main/res/drawable-xxhdpi/delete_row.png index 79ef9da828ba75a07e02dbaaf32f4fb05899f390..9ccd36dcd7c50e073f3b7c29588b7504db15b670 100644 GIT binary patch literal 7627 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 Qe>%vWp00i_>zopr0Ff(MEdT%j diff --git a/sample/src/main/res/drawable-xxhdpi/insert_column.png b/sample/src/main/res/drawable-xxhdpi/insert_column.png index 49353f2d1c3ae48cde349c3c0c8e122f74d2996d..308b8e683c38b69545c667038ec63e723acf96c1 100644 GIT binary patch literal 8354 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 M#{^b+{&K|s02yZT?f?J) literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#X#z`$7N>Eakt zG3V_~L;ph#630G1H@#bM;o^)8nLq#JkDWYn#8sW0?WV#$K2g(SyVb8TRek@jsxu|~ zmi=+j6;~S1>^b{BcK1g2-xde#6Etl07cy7#mrS1dd~4%g_9&04mAr3kC#2Y=ZEgJT zmll^fM{u@&|H;OrZHuipoT-^sVw3nH=u%Yj3gg-=A;F86cxF}UE#KO!yVlXVax-Vj z7Lg3~sHo<5DzRBHDbANBANwq=GWSnGJb(VPshiMRreTmpl3K z7cTK=t*m43>PXEk;LpDBM88w0kz+~G0(Z|p@<6K8Ws2DQ^3Cx_jf|h)d#?D^pt-Kq zfvu5;Ns`6r+qYn4rL>(%)7DMeeaqhXgu(RKbLh*2~7Zlva})q diff --git a/sample/src/main/res/drawable-xxhdpi/insert_row.png b/sample/src/main/res/drawable-xxhdpi/insert_row.png index 8165061d72b33fba08597547c1d89c8e5ef4cdfa..b5fa5cd2ddb3c432551c08ce83e4ced7102ee1d5 100644 GIT binary patch literal 7639 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 literal 283 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 literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!EX7WqAsj$Z!;#Vf6S3j3^P6 Date: Wed, 28 Dec 2022 11:41:05 +0100 Subject: [PATCH 020/136] optimize insertImage & video --- richeditor/src/main/assets/rich_editor.js | 35 ++++++++++++++++--- .../jp/wasabeef/richeditor/RichEditor.java | 4 +-- sample/src/main/AndroidManifest.xml | 4 +-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 7bd94ae..497a381 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -272,19 +272,44 @@ RE.setLineHeight = function(height) { RE.editor.style.lineHeight = height; }; -RE.insertImage = function(url, alt) { +RE.setBlockquote = function() { + document.execCommand('formatBlock', false, '
'); +}; + +RE.insertImage = function(url, alt="", width="", height="" ) { var img = document.createElement('img'); img.setAttribute("src", url); - img.setAttribute("alt", alt); + if (alt != "") img.setAttribute("alt", alt); + if (width != "") img.setAttribute("width", width); + if (height != "") img.setAttribute("height", height); img.onload = RE.updateHeight; RE.insertHTML(img.outerHTML); RE.callback("input"); }; -RE.setBlockquote = function() { - document.execCommand('formatBlock', false, '
'); -}; +RE.insertVideo = function(url, width="", height="") { + var video = document.createElement('video'); + video.setAttribute("src", url); + video.controls = true; + video.muted = false; + if (width != "") video.setAttribute("width", width); + if (height != "") video.setAttribute("height", height); + video.onload = RE.updateHeight; + + RE.insertHTML(video.outerHTML); + RE.callback("input"); +} + +RE.insertAudio = function(url, alt) { + var html = '
'; + RE.insertHTML(html); +} + +RE.insertYoutubeVideo = function(url, width="100%", height="100%") { + var html = '
' + RE.insertHTML(html); +} RE.insertHTML = function(html) { RE.restorerange(); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index f3067a7..6eae5ec 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -442,7 +442,7 @@ public void insertImage(String url, String alt) { */ public void insertImage(String url, String alt, int width) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImageW('" + url + "', '" + alt + "','" + width + "');"); + exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "');"); } /** @@ -456,7 +456,7 @@ public void insertImage(String url, String alt, int width) { */ public void insertImage(String url, String alt, int width, int height) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImageWH('" + url + "', '" + alt + "','" + width + "', '" + height + "');"); + exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "');"); } public void insertVideo(String url) { diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 2a7b31f..a74e213 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -1,9 +1,7 @@ + package="jp.wasabeef.sample"> From 2cc31e2c06cf11756cfe7aab8d9afa6ff97f1aff Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 15:03:27 +0100 Subject: [PATCH 021/136] optimize insertImage & video --- richeditor/src/main/assets/rich_editor.js | 79 +++++++++++++++++-- .../jp/wasabeef/richeditor/RichEditor.java | 8 +- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 497a381..8f4f379 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -14,6 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + + /** + * See about document.execCommand: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand + */ + "use strict"; var RE = {}; @@ -341,13 +346,13 @@ RE.prepareInsert = function() { RE.backuprange = function() { var selection = window.getSelection(); if (selection.rangeCount > 0) { - var range = selection.getRangeAt(0); - RE.currentSelection = { - "startContainer": range.startContainer, - "startOffset": range.startOffset, - "endContainer": range.endContainer, - "endOffset": range.endOffset - }; + var range = selection.getRangeAt(0); + RE.currentSelection = { + "startContainer": range.startContainer, + "startOffset": range.startOffset, + "endContainer": range.endContainer, + "endOffset": range.endOffset + }; } }; @@ -548,3 +553,63 @@ RE.getRelativeCaretYPosition = function() { window.onload = function() { RE.callback("ready"); }; + +RE.enabledEditingItems = function(e) { + var items = []; + if (document.queryCommandState('bold')) { + items.push('bold'); + } + if (document.queryCommandState('italic')) { + items.push('italic'); + } + if (document.queryCommandState('subscript')) { + items.push('subscript'); + } + if (document.queryCommandState('superscript')) { + items.push('superscript'); + } + if (document.queryCommandState('strikeThrough')) { + items.push('strikeThrough'); + } + if (document.queryCommandState('underline')) { + items.push('underline'); + } + if (document.queryCommandState('insertOrderedList')) { + items.push('orderedList'); + } + if (document.queryCommandState('insertUnorderedList')) { + items.push('unorderedList'); + } + if (document.queryCommandState('justifyCenter')) { + items.push('justifyCenter'); + } + if (document.queryCommandState('justifyFull')) { + items.push('justifyFull'); + } + if (document.queryCommandState('justifyLeft')) { + items.push('justifyLeft'); + } + if (document.queryCommandState('justifyRight')) { + items.push('justifyRight'); + } + if (document.queryCommandState('insertHorizontalRule')) { + items.push('horizontalRule'); + } + var formatBlock = document.queryCommandValue('formatBlock'); + if (formatBlock.length > 0) { + items.push(formatBlock); + } + + window.location.href = "re-state://" + encodeURI(items.join(',')); +} + + +// Event Listeners +RE.editor.addEventListener("input", RE.callback); +RE.editor.addEventListener("keyup", function(e) { + var KEY_LEFT = 37, KEY_RIGHT = 39; + if (e.which == KEY_LEFT || e.which == KEY_RIGHT) { + RE.enabledEditingItems(e); + } +}); +RE.editor.addEventListener("click", RE.enabledEditingItems); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 6eae5ec..862862b 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -466,12 +466,12 @@ public void insertVideo(String url) { public void insertVideo(String url, int width) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertVideoW('" + url + "', '" + width + "');"); + exec("javascript:RE.insertVideo('" + url + "', '" + width + "');"); } public void insertVideo(String url, int width, int height) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertVideoWH('" + url + "', '" + width + "', '" + height + "');"); + exec("javascript:RE.insertVideo('" + url + "', '" + width + "', '" + height + "');"); } public void insertAudio(String url) { @@ -486,12 +486,12 @@ public void insertYoutubeVideo(String url) { public void insertYoutubeVideo(String url, int width) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertYoutubeVideoW('" + url + "', '" + width + "');"); + exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "');"); } public void insertYoutubeVideo(String url, int width, int height) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertYoutubeVideoWH('" + url + "', '" + width + "', '" + height + "');"); + exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "', '" + height + "');"); } public void insertLink(String href, String title) { From 534c039d803ef74d17eddd538a6fe531a764e672 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 15:14:15 +0100 Subject: [PATCH 022/136] build updates, new version --- gradle.properties | 6 +++--- sample/build.gradle | 2 +- sample/src/main/AndroidManifest.xml | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6b00a86..5517438 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,11 +19,11 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=2.0.0 -VERSION_CODE=200 +VERSION_NAME=3.0.0pre +VERSION_CODE=299 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=33 -TARGET_SDK_VERSION=30 +TARGET_SDK_VERSION=33 MIN_SDK_VERSION=24 diff --git a/sample/build.gradle b/sample/build.gradle index d2905da..420168f 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -37,5 +37,5 @@ repositories { dependencies { implementation project(':richeditor') - implementation "androidx.appcompat:appcompat:1.2.0" + implementation "androidx.appcompat:appcompat:1.5.1" } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index a74e213..c0885ba 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -13,7 +13,9 @@ tools:ignore="GoogleAppIndexingWarning"> + android:label="@string/title_activity_main" + android:exported="true" + > From 233606a59736132c5619d419b48587328eabc04f Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 15:23:50 +0100 Subject: [PATCH 023/136] normalize.css to v8.0.1 --- richeditor/src/main/assets/normalize.css | 138 ++++++++++++----------- 1 file changed, 73 insertions(+), 65 deletions(-) diff --git a/richeditor/src/main/assets/normalize.css b/richeditor/src/main/assets/normalize.css index c2cff88..192eb9c 100644 --- a/richeditor/src/main/assets/normalize.css +++ b/richeditor/src/main/assets/normalize.css @@ -1,7 +1,7 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ + ========================================================================== */ /** * 1. Correct the line height in all browsers. @@ -9,19 +9,27 @@ */ html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections - ========================================================================== */ + ========================================================================== */ /** * Remove the margin in all browsers. */ body { - margin: 0; + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; } /** @@ -30,12 +38,12 @@ body { */ h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } /* Grouping content - ========================================================================== */ + ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. @@ -43,9 +51,9 @@ h1 { */ hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } /** @@ -54,19 +62,19 @@ hr { */ pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /* Text-level semantics - ========================================================================== */ + ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { - background-color: transparent; + background-color: transparent; } /** @@ -75,9 +83,9 @@ a { */ abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /** @@ -86,7 +94,7 @@ abbr[title] { b, strong { - font-weight: bolder; + font-weight: bolder; } /** @@ -97,8 +105,8 @@ strong { code, kbd, samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** @@ -106,7 +114,7 @@ samp { */ small { - font-size: 80%; + font-size: 80%; } /** @@ -116,33 +124,33 @@ small { sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } /* Embedded content - ========================================================================== */ + ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { - border-style: none; + border-style: none; } /* Forms - ========================================================================== */ + ========================================================================== */ /** * 1. Change the font styles in all browsers. @@ -154,10 +162,10 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** @@ -167,7 +175,7 @@ textarea { button, input { /* 1 */ - overflow: visible; + overflow: visible; } /** @@ -177,7 +185,7 @@ input { /* 1 */ button, select { /* 1 */ - text-transform: none; + text-transform: none; } /** @@ -188,7 +196,7 @@ button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } /** @@ -199,8 +207,8 @@ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; + border-style: none; + padding: 0; } /** @@ -211,7 +219,7 @@ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } /** @@ -219,7 +227,7 @@ button:-moz-focusring, */ fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } /** @@ -230,12 +238,12 @@ fieldset { */ legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } /** @@ -243,7 +251,7 @@ legend { */ progress { - vertical-align: baseline; + vertical-align: baseline; } /** @@ -251,7 +259,7 @@ progress { */ textarea { - overflow: auto; + overflow: auto; } /** @@ -261,8 +269,8 @@ textarea { [type="checkbox"], [type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } /** @@ -271,7 +279,7 @@ textarea { [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } /** @@ -280,8 +288,8 @@ textarea { */ [type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** @@ -289,7 +297,7 @@ textarea { */ [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } /** @@ -298,19 +306,19 @@ textarea { */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } /* Interactive - ========================================================================== */ + ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { - display: block; + display: block; } /* @@ -318,18 +326,18 @@ details { */ summary { - display: list-item; + display: list-item; } /* Misc - ========================================================================== */ + ========================================================================== */ /** * Add the correct display in IE 10+. */ template { - display: none; + display: none; } /** @@ -337,5 +345,5 @@ template { */ [hidden] { - display: none; + display: none; } From 42cbb9acf9235057ced093eac2cdae5e7bc5c359 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 15:32:28 +0100 Subject: [PATCH 024/136] update gradle to 7.6 --- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 269 ++++++++++++++--------- gradlew.bat | 15 +- 4 files changed, 175 insertions(+), 112 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 39316 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 delta 36846 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 CcabXq diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41dfb87..f398c33 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0..65dcd68 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,105 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 6d5c8854def6f43a24b487f5895e6d4f92b4e032 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 15:33:10 +0100 Subject: [PATCH 025/136] update gradle to 7.6 --- gradle/wrapper/gradle-wrapper.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f398c33..eff7a3b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -4,3 +4,5 @@ distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +Sha256Sum=7ba68c54029790ab444b39d7e293d3236b2632631fb5f2e012bb28b4ff669e4b +#distributionSha256Sum=7ba68c54029790ab444b39d7e293d3236b2632631fb5f2e012bb28b4ff669e4b From 3f00e9e36de991cd8c5106993ec2133683d1e612 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 16:28:43 +0100 Subject: [PATCH 026/136] Revert "normalize.css to v8.0.1" This reverts commit 233606a59736132c5619d419b48587328eabc04f. --- richeditor/src/main/assets/normalize.css | 138 +++++++++++------------ 1 file changed, 65 insertions(+), 73 deletions(-) diff --git a/richeditor/src/main/assets/normalize.css b/richeditor/src/main/assets/normalize.css index 192eb9c..c2cff88 100644 --- a/richeditor/src/main/assets/normalize.css +++ b/richeditor/src/main/assets/normalize.css @@ -1,7 +1,7 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ + ========================================================================== */ /** * 1. Correct the line height in all browsers. @@ -9,27 +9,19 @@ */ html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections - ========================================================================== */ + ========================================================================== */ /** * Remove the margin in all browsers. */ body { - margin: 0; -} - -/** - * Render the `main` element consistently in IE. - */ - -main { - display: block; + margin: 0; } /** @@ -38,12 +30,12 @@ main { */ h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } /* Grouping content - ========================================================================== */ + ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. @@ -51,9 +43,9 @@ h1 { */ hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } /** @@ -62,19 +54,19 @@ hr { */ pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /* Text-level semantics - ========================================================================== */ + ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { - background-color: transparent; + background-color: transparent; } /** @@ -83,9 +75,9 @@ a { */ abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /** @@ -94,7 +86,7 @@ abbr[title] { b, strong { - font-weight: bolder; + font-weight: bolder; } /** @@ -105,8 +97,8 @@ strong { code, kbd, samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** @@ -114,7 +106,7 @@ samp { */ small { - font-size: 80%; + font-size: 80%; } /** @@ -124,33 +116,33 @@ small { sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } /* Embedded content - ========================================================================== */ + ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { - border-style: none; + border-style: none; } /* Forms - ========================================================================== */ + ========================================================================== */ /** * 1. Change the font styles in all browsers. @@ -162,10 +154,10 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** @@ -175,7 +167,7 @@ textarea { button, input { /* 1 */ - overflow: visible; + overflow: visible; } /** @@ -185,7 +177,7 @@ input { /* 1 */ button, select { /* 1 */ - text-transform: none; + text-transform: none; } /** @@ -196,7 +188,7 @@ button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } /** @@ -207,8 +199,8 @@ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; + border-style: none; + padding: 0; } /** @@ -219,7 +211,7 @@ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } /** @@ -227,7 +219,7 @@ button:-moz-focusring, */ fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } /** @@ -238,12 +230,12 @@ fieldset { */ legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } /** @@ -251,7 +243,7 @@ legend { */ progress { - vertical-align: baseline; + vertical-align: baseline; } /** @@ -259,7 +251,7 @@ progress { */ textarea { - overflow: auto; + overflow: auto; } /** @@ -269,8 +261,8 @@ textarea { [type="checkbox"], [type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } /** @@ -279,7 +271,7 @@ textarea { [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } /** @@ -288,8 +280,8 @@ textarea { */ [type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** @@ -297,7 +289,7 @@ textarea { */ [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } /** @@ -306,19 +298,19 @@ textarea { */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } /* Interactive - ========================================================================== */ + ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { - display: block; + display: block; } /* @@ -326,18 +318,18 @@ details { */ summary { - display: list-item; + display: list-item; } /* Misc - ========================================================================== */ + ========================================================================== */ /** * Add the correct display in IE 10+. */ template { - display: none; + display: none; } /** @@ -345,5 +337,5 @@ template { */ [hidden] { - display: none; + display: none; } From 65b016093a5a775df0a8278d4d7796d2dd919657 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 20:08:06 +0100 Subject: [PATCH 027/136] Revert "Revert "normalize.css to v8.0.1"" This reverts commit 3f00e9e36de991cd8c5106993ec2133683d1e612. --- richeditor/src/main/assets/normalize.css | 138 ++++++++++++----------- 1 file changed, 73 insertions(+), 65 deletions(-) diff --git a/richeditor/src/main/assets/normalize.css b/richeditor/src/main/assets/normalize.css index c2cff88..192eb9c 100644 --- a/richeditor/src/main/assets/normalize.css +++ b/richeditor/src/main/assets/normalize.css @@ -1,7 +1,7 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ + ========================================================================== */ /** * 1. Correct the line height in all browsers. @@ -9,19 +9,27 @@ */ html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections - ========================================================================== */ + ========================================================================== */ /** * Remove the margin in all browsers. */ body { - margin: 0; + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; } /** @@ -30,12 +38,12 @@ body { */ h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } /* Grouping content - ========================================================================== */ + ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. @@ -43,9 +51,9 @@ h1 { */ hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ } /** @@ -54,19 +62,19 @@ hr { */ pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /* Text-level semantics - ========================================================================== */ + ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { - background-color: transparent; + background-color: transparent; } /** @@ -75,9 +83,9 @@ a { */ abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /** @@ -86,7 +94,7 @@ abbr[title] { b, strong { - font-weight: bolder; + font-weight: bolder; } /** @@ -97,8 +105,8 @@ strong { code, kbd, samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** @@ -106,7 +114,7 @@ samp { */ small { - font-size: 80%; + font-size: 80%; } /** @@ -116,33 +124,33 @@ small { sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } /* Embedded content - ========================================================================== */ + ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { - border-style: none; + border-style: none; } /* Forms - ========================================================================== */ + ========================================================================== */ /** * 1. Change the font styles in all browsers. @@ -154,10 +162,10 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** @@ -167,7 +175,7 @@ textarea { button, input { /* 1 */ - overflow: visible; + overflow: visible; } /** @@ -177,7 +185,7 @@ input { /* 1 */ button, select { /* 1 */ - text-transform: none; + text-transform: none; } /** @@ -188,7 +196,7 @@ button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } /** @@ -199,8 +207,8 @@ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; + border-style: none; + padding: 0; } /** @@ -211,7 +219,7 @@ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; + outline: 1px dotted ButtonText; } /** @@ -219,7 +227,7 @@ button:-moz-focusring, */ fieldset { - padding: 0.35em 0.75em 0.625em; + padding: 0.35em 0.75em 0.625em; } /** @@ -230,12 +238,12 @@ fieldset { */ legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } /** @@ -243,7 +251,7 @@ legend { */ progress { - vertical-align: baseline; + vertical-align: baseline; } /** @@ -251,7 +259,7 @@ progress { */ textarea { - overflow: auto; + overflow: auto; } /** @@ -261,8 +269,8 @@ textarea { [type="checkbox"], [type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } /** @@ -271,7 +279,7 @@ textarea { [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } /** @@ -280,8 +288,8 @@ textarea { */ [type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** @@ -289,7 +297,7 @@ textarea { */ [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } /** @@ -298,19 +306,19 @@ textarea { */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } /* Interactive - ========================================================================== */ + ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { - display: block; + display: block; } /* @@ -318,18 +326,18 @@ details { */ summary { - display: list-item; + display: list-item; } /* Misc - ========================================================================== */ + ========================================================================== */ /** * Add the correct display in IE 10+. */ template { - display: none; + display: none; } /** @@ -337,5 +345,5 @@ template { */ [hidden] { - display: none; + display: none; } From e30c9dede3c6a27729f8792bd290d9b4947818f1 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 20:46:55 +0100 Subject: [PATCH 028/136] add CollapsibleSection --- README.md | 3 +- richeditor/src/main/assets/rich_editor.js | 26 +++++++++++++ richeditor/src/main/assets/style.css | 36 ++++++++++++++++++ .../jp/wasabeef/richeditor/RichEditor.java | 5 ++- .../java/jp/wasabeef/sample/MainActivity.java | 8 ++++ .../res/drawable-xxhdpi/insert_section.png | Bin 0 -> 9130 bytes sample/src/main/res/layout/activity_main.xml | 8 ++++ 7 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/insert_section.png diff --git a/README.md b/README.md index e1c9e08..d096d65 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ Supported Functions - [x] Ordered List (Numbers) - [x] (new) Get Selected Text - [x] (new) Get Selected Href -- [x] (new) Insert Table +- [x] (new) Table +- [x] (new) Collapsible Section Attribute change of editor --- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 8f4f379..070182b 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -316,6 +316,32 @@ RE.insertYoutubeVideo = function(url, width="100%", height="100%") { RE.insertHTML(html); } +RE.insertCollapsibleSection = function(section, content) { + var d = document.createElement("button"); + d.setAttribute("class", "collapsible"); + d.innerHTML = section; + d.addEventListener("click", function() { + this.classList.toggle("active"); + var content = this.nextElementSibling; + if (content.style.maxHeight){ + content.style.maxHeight = null; + } else { + content.style.maxHeight = content.scrollHeight + "px"; + } + }); + var elements = document.querySelectorAll(":hover"); + d=elements[elements.length - 1].appendChild(d); + var e=document.createElement("div"); + e.setAttribute("class", "content"); + e.innerHTML = '

' + content + '

'; + elements[elements.length - 1].appendChild(e); + + // next empty element + e=document.createElement("p"); + e.innerHTML = '
'; + elements[elements.length - 1].appendChild(e); +} + RE.insertHTML = function(html) { RE.restorerange(); document.execCommand('insertHTML', false, html); diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index e5dae6f..71b734c 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -82,3 +82,39 @@ table {overflow-x: scroll;} th, td {max-width: 200px; min-width:50px;} table, td, th{border-collapse:collapse; border:1px solid #777;} td{padding:5px 10px; height:35px;} + +.collapsible { + background-color: #777; + color: white; + cursor: pointer; + padding: 18px; + width: 100%; + border: none; + text-align: left; + outline: none; + font-size: 15px; +} + +.active, .collapsible:hover { + background-color: #555; +} + +.collapsible:after { + content: '\002B'; + color: white; + font-weight: bold; + float: right; + margin-left: 5px; +} + +.active:after { + content: "\2212"; +} + +.content { + padding: 0 18px; + max-height: 0; + overflow: hidden; + transition: max-height 0.2s ease-out; + background-color: #f1f1f1; +} diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 862862b..0458b53 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -427,6 +427,9 @@ public void insertHR_Line() { exec("javascript:RE.insertHTML('
')"); } + public void insertCollapsibleSection(String section, String content) { + exec("javascript:RE.insertCollapsibleSection('"+section+"', '"+content+"');"); + } public void insertImage(String url, String alt) { exec("javascript:RE.prepareInsert();"); @@ -501,7 +504,7 @@ public void insertLink(String href, String title) { public String insertCheckbox(String uuid) { if (uuid.isEmpty()) - uuid = UUID.randomUUID().toString();; + uuid = UUID.randomUUID().toString(); exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setCheckbox('"+ uuid +"')"); return uuid; diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 63f8778..c4b46f1 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -243,6 +243,14 @@ public void onClick(View v) { } }); + findViewById(R.id.action_insert_section).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.insertCollapsibleSection("Section","content"); + } + }); + + findViewById(R.id.action_insert_image).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/sample/src/main/res/drawable-xxhdpi/insert_section.png b/sample/src/main/res/drawable-xxhdpi/insert_section.png new file mode 100644 index 0000000000000000000000000000000000000000..201174b5fbdcae75fc31060991328c51f7c194b6 GIT binary patch literal 9130 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 + + Date: Wed, 28 Dec 2022 20:52:33 +0100 Subject: [PATCH 029/136] add CollapsibleSection --- .../res/drawable-xxhdpi/insert_section.png | Bin 9130 -> 8849 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sample/src/main/res/drawable-xxhdpi/insert_section.png b/sample/src/main/res/drawable-xxhdpi/insert_section.png index 201174b5fbdcae75fc31060991328c51f7c194b6..0786d3ba085bf585b787a7820fa96a81e414d26a 100644 GIT binary patch delta 4969 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 KMNUMnLSTY1vGmvg From 091a71309ff0be6b0ab30e4cfcfaa5572655e535 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 20:59:32 +0100 Subject: [PATCH 030/136] add insertImageAsBase64 --- README.md | 10 ++++---- .../jp/wasabeef/richeditor/RichEditor.java | 24 +++++++++++++++++-- .../java/jp/wasabeef/richeditor/Utils.java | 15 ++++++------ .../java/jp/wasabeef/sample/MainActivity.java | 17 ++++++------- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index d096d65..79c6bcf 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Supported Functions - [x] (new) Insert HTML Code - [x] (new) Insert Horizontal Line - [x] Insert Image +- [x] (new) Insert Inline Image - [x] Insert Youtube - [x] Insert Video - [x] Insert Audio @@ -65,6 +66,7 @@ Supported Functions - [x] (new) Get Selected Href - [x] (new) Table - [x] (new) Collapsible Section +- [x] (new) Run and acquire data direct from JavaScript (requestJSData) Attribute change of editor --- @@ -177,10 +179,10 @@ Applications using RichEditor for Android Please [ping](mailto:dadadada.chop@gmail.com) me or send a pull request if you would like to be added here. -Icon | Application ------------- | ------------- - | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) - | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) +| Icon | Application| +|----------------------------------------------------------------------------------------------------------------------------------------------------| -------------| +| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid)| +< | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal)| Developed By ------- diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 0458b53..a7377d5 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; @@ -18,6 +19,8 @@ import android.webkit.WebView; import android.webkit.WebViewClient; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; @@ -275,7 +278,7 @@ public void setBackgroundColor(int color) { @Override public void setBackgroundResource(int resid) { Bitmap bitmap = Utils.decodeResource(getContext(), resid); - String base64 = Utils.toBase64(bitmap); + String base64 = Utils.toBase64(bitmap, "png"); bitmap.recycle(); exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');"); @@ -284,7 +287,7 @@ public void setBackgroundResource(int resid) { @Override public void setBackground(Drawable background) { Bitmap bitmap = Utils.toBitmap(background); - String base64 = Utils.toBase64(bitmap); + String base64 = Utils.toBase64(bitmap,"png"); bitmap.recycle(); exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');"); @@ -462,6 +465,23 @@ public void insertImage(String url, String alt, int width, int height) { exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "');"); } + public void insertImageAsBase64(Uri imageURI, String alt) { + InputStream inputStream= null; + try { + inputStream = getContext().getContentResolver().openInputStream(imageURI); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); + String format="png"; + String tag = "data:image/" + format + ";charset=utf-8;base64,"; + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "',"+alt+");"); + //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); + } + public void insertVideo(String url) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertVideo('" + url + "');"); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java index 2f4a2a1..1752ca0 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java @@ -32,12 +32,16 @@ private Utils() throws InstantiationException { throw new InstantiationException("This class is not for instantiation"); } - public static String toBase64(Bitmap bitmap) { + public static String toBase64(Bitmap bitmap, String type) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); - byte[] bytes = baos.toByteArray(); + if (type.equals("jpg") || type.equals("jpeg") ) + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); + else if(type.equals("png")) + bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); + else if(type.equals("webp")) + bitmap.compress(Bitmap.CompressFormat.WEBP, 100, baos); - return Base64.encodeToString(bytes, Base64.NO_WRAP); + return Base64.encodeToString(baos.toByteArray(), Base64.NO_WRAP); } public static Bitmap toBitmap(Drawable drawable) { @@ -62,7 +66,4 @@ public static Bitmap decodeResource(Context context, int resId) { return BitmapFactory.decodeResource(context.getResources(), resId); } - public static long getCurrentTime() { - return System.currentTimeMillis(); - } } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index c4b46f1..98bc56f 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -1,6 +1,7 @@ package jp.wasabeef.sample; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.TextView; @@ -14,12 +15,6 @@ public class MainActivity extends AppCompatActivity { private RichEditor mEditor; private TextView mPreview; - public boolean onReceiveValue(String value) { - String test = value; - test=test+" "; - return true; - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -254,8 +249,14 @@ public void onClick(View v) { findViewById(R.id.action_insert_image).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", - "dachshund", 320); + String image; + image=getContentResolver().SCHEME_ANDROID_RESOURCE + + "://" + getResources().getResourcePackageName(R.drawable.insert_image) + + '/' + getResources().getResourceTypeName(R.drawable.insert_image) + '/' + getResources().getResourceEntryName(R.drawable.bg_color); + // image="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Hyoscyamus_niger_0003.JPG/449px-Hyoscyamus_niger_0003.JPG"; + image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; + mEditor.insertImageAsBase64(Uri.parse(image),"alt"); + //mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", 320); } }); From bc8b755db037e40bb6ae7bc26419d94d3edfc39c Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 28 Dec 2022 21:00:05 +0100 Subject: [PATCH 031/136] add insertImageAsBase64 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 79c6bcf..a4e2edb 100644 --- a/README.md +++ b/README.md @@ -189,8 +189,7 @@ Developed By Daichi Furiya (Wasabeef) -
-Follow me on Twitter +Follow me on Twitter Thanks From 8248a70d24d02698dff86eb38bef655d1f4ba473 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 31 Dec 2022 15:06:38 +0100 Subject: [PATCH 032/136] fundamental fixes to get it run --- README.md | 1 + richeditor/src/main/assets/rich_editor.js | 94 ++++++++++++------- richeditor/src/main/assets/style.css | 1 + .../jp/wasabeef/richeditor/RichEditor.java | 39 ++++++-- .../java/jp/wasabeef/sample/MainActivity.java | 1 + 5 files changed, 95 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index a4e2edb..8229480 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Attribute change of editor - [x] Placeholder - [x] Load CSS - [x] State Callback +- [x] (new) setHTML_asCallBack (don't encode & copy the complete HTML page on every change by callback) **Milestone** diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 070182b..ad5471d 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2022 niendo + * Copyright (C) 2022 peter@niendo.de * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +25,15 @@ var RE = {}; RE.editor = document.getElementById('editor'); +// in v2.0.0 each change, will raise a callback, which encodes and copy the complete HTML code back to java, +// this is very resource eating. +// with HTML_asCallBack=true, getHTML will be a normal callback +RE.getHTML_asCallBack = false; + +RE.setHTML_asCallBack = function(value) { + RE.getHTML_asCallBack = Boolean(value); +}; + // Not universally supported, but seems to work in iOS 7 and 8 document.addEventListener("selectionchange", function() { RE.backuprange(); @@ -87,7 +96,11 @@ RE.runCallbackQueue = function() { } setTimeout(function() { - window.location.href = "re-callback://"; + if (RE.getHTML_asCallBack == true) { + window.location.href = "re-callback://"; + } else { + window.location.href = "re-callback://" + RE.getHtml(); + } }, 0); }; @@ -103,24 +116,24 @@ RE.callback = function(method) { }; RE.setHtml = function(contents) { - var tempWrapper = document.createElement('div'); - tempWrapper.innerHTML = contents; - var images = tempWrapper.querySelectorAll("img"); + RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));; + var images = RE.editor.querySelectorAll("img"); for (var i = 0; i < images.length; i++) { images[i].onload = RE.updateHeight; } - RE.editor.innerHTML = tempWrapper.innerHTML; + //RE.editor.innerHTML = tempWrapper.innerHTML; RE.updatePlaceholder(); + RE.callback("input"); }; RE.getHtml = function() { - return RE.editor.innerHTML; + return encodeURIComponent(RE.editor.innerHTML); }; RE.getText = function() { - return RE.editor.innerText; + return encodeURIComponent(RE.editor.innerText); }; RE.setBaseTextColor = function(color) { @@ -150,10 +163,6 @@ RE.updatePlaceholder = function() { } }; -RE.removeFormat = function() { - document.execCommand('removeFormat', false, null); -}; - RE.setFontSize = function(size) { RE.editor.style.fontSize = size; }; @@ -166,6 +175,18 @@ RE.setHeight = function(size) { RE.editor.style.height = size; }; +RE.setTextAlign = function(align) { + RE.editor.style.textAlign = align; +} + +RE.setVerticalAlign = function(align) { + RE.editor.style.verticalAlign = align; +} + +RE.setInputEnabled = function(inputEnabled) { + RE.editor.contentEditable = String(inputEnabled); +} + RE.undo = function() { document.execCommand('undo', false, null); }; @@ -407,28 +428,6 @@ RE.restorerange = function() { selection.addRange(range); }; -RE.focus = function() { - var range = document.createRange(); - range.selectNodeContents(RE.editor); - range.collapse(false); - var selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange(range); - RE.editor.focus(); -}; - -RE.focusAtPoint = function(x, y) { - var range = document.caretRangeFromPoint(x, y) || document.createRange(); - var selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange(range); - RE.editor.focus(); -}; - -RE.blurFocus = function() { - RE.editor.blur(); -}; - // User editing table functionality RE.insertTable = function(width, height) { var table = document.createElement("table"); @@ -629,7 +628,33 @@ RE.enabledEditingItems = function(e) { window.location.href = "re-state://" + encodeURI(items.join(',')); } +RE.focus = function() { + var range = document.createRange(); + range.selectNodeContents(RE.editor); + range.collapse(false); + var selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + RE.editor.focus(); +}; + +RE.focusAtPoint = function(x, y) { + var range = document.caretRangeFromPoint(x, y) || document.createRange(); + var selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + RE.editor.focus(); +}; + +RE.blurFocus = function() { + RE.editor.blur(); +}; + +RE.removeFormat = function() { + document.execCommand('removeFormat', false, null); +}; +/* // Event Listeners RE.editor.addEventListener("input", RE.callback); RE.editor.addEventListener("keyup", function(e) { @@ -639,3 +664,4 @@ RE.editor.addEventListener("keyup", function(e) { } }); RE.editor.addEventListener("click", RE.enabledEditingItems); +*/ diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index 71b734c..bc0c05b 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -1,4 +1,5 @@ /** + * Copyright (C) 2015 peter@niendo.de * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index a7377d5..a265775 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -20,9 +20,11 @@ import android.webkit.WebViewClient; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -77,6 +79,7 @@ public interface AfterInitialLoadListener { private static final String SETUP_HTML = "file:///android_asset/rich_editor.html"; private static final String CALLBACK_SCHEME = "re-callback://"; private static final String STATE_SCHEME = "re-state://"; + private static boolean HTML_asCallBack = false; private boolean isReady = false; private String mContents; private OnTextChangeListener mTextChangeListener; @@ -128,11 +131,14 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { @Override public void onReceiveValue(String value) { - String unescaped=""; - if ("null".equals(value)) { - - } else { - unescaped = value.substring(1, value.length() - 1) // remove wrapping quotes + String unescaped= null; + try { + unescaped = URLDecoder.decode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + if (!"null".equals(unescaped)) { + unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes .replace("\\\\", "\\") // unescape \\ -> \ .replace("\\\"", "\""); // unescape \" -> " } @@ -211,7 +217,13 @@ public void setHtml(String contents) { } public String getHtml() { - return mContents; + if(HTML_asCallBack) { + requestJSData("RE.getHtml()"); + return("data can only received by callback"); + } else { + // only for compatibility + return mContents; + } } /// Text representation of the data that has been input into the editor view, if it has been loaded. @@ -234,6 +246,14 @@ public boolean getSelectedHref() { } } + // in v2.0.0 each change, will raise a callback, which encodes and copy the complete HTML code back to java, + // this is very resource eating. + // with HTML_asCallBack=true, getHTML will be a normal callback + public void setHTML_asCallBack(Boolean value) { + HTML_asCallBack = value; + exec("javascript:RE.setHTML_asCallBack(" + value + ");"); + } + /// Whether or not the selection has a type specifically of "Range". public boolean hasRangeSelection() { return requestJSData("RE.rangeSelectionExists()"); @@ -474,7 +494,12 @@ public void insertImageAsBase64(Uri imageURI, String alt) { } Bitmap bitmap = BitmapFactory.decodeStream(inputStream); - //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); String format="png"; String tag = "data:image/" + format + ";charset=utf-8;base64,"; exec("javascript:RE.prepareInsert();"); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 98bc56f..fa8bc48 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -32,6 +32,7 @@ protected void onCreate(Bundle savedInstanceState) { //mEditor.setInputEnabled(false); mPreview = (TextView) findViewById(R.id.preview); + mEditor.setHTML_asCallBack(true); mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { From 56a5d0bfe70b863c74ff1a21cb0bf4358fc17b86 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 31 Dec 2022 17:15:03 +0100 Subject: [PATCH 033/136] update libs --- richeditor/build.gradle | 4 ++-- .../src/test/java/richeditor/UrlDecoderTest.java | 3 +-- .../java/jp/wasabeef/sample/MainActivity.java | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/richeditor/build.gradle b/richeditor/build.gradle index 4c76ccb..c4fb5c3 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -11,8 +11,8 @@ android { dependencies { - testImplementation "junit:junit:4.13" - testImplementation "org.robolectric:robolectric:4.3.1" + testImplementation 'junit:junit:4.13.2' + //testImplementation 'org.robolectric:robolectric:4.9.2' } ext { diff --git a/richeditor/src/test/java/richeditor/UrlDecoderTest.java b/richeditor/src/test/java/richeditor/UrlDecoderTest.java index 78b0e49..e1ad7fc 100644 --- a/richeditor/src/test/java/richeditor/UrlDecoderTest.java +++ b/richeditor/src/test/java/richeditor/UrlDecoderTest.java @@ -5,9 +5,8 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +//@RunWith(RobolectricTestRunner.class) public class UrlDecoderTest { @Test diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index fa8bc48..995ca04 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -57,7 +57,20 @@ public void onClick(View v) { findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setBold(); + + + mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { + @Override public void onDataReceived(String value) { + String temp; + if(!value.isEmpty()) + temp=value; + } + }); + + mEditor.getHtml(); + + + //mEditor.setBold(); } }); From 043678aad85992dd7160dfb0aa0034f1a722945a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 31 Dec 2022 20:04:28 +0100 Subject: [PATCH 034/136] add remove_format to sample app --- README.md | 11 ++++++----- .../java/jp/wasabeef/sample/MainActivity.java | 7 +++++++ .../main/res/drawable-xxhdpi/remove_format.png | Bin 0 -> 2551 bytes sample/src/main/res/layout/activity_main.xml | 8 ++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/remove_format.png diff --git a/README.md b/README.md index 8229480..4e44926 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Supported Functions ![Toolbar](./art/demo.gif) +- [x] (new?) Remove Format - [x] Bold - [x] Italic - [x] Subscript @@ -159,7 +160,7 @@ editor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/twitte **Text Change Listener** ```java RichEditor editor = (RichEditor) findViewById(R.id.editor); -editor. setOnTextChangeListener(new RichEditor.OnTextChangeListener() { +editor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { // Do Something @@ -180,10 +181,10 @@ Applications using RichEditor for Android Please [ping](mailto:dadadada.chop@gmail.com) me or send a pull request if you would like to be added here. -| Icon | Application| -|----------------------------------------------------------------------------------------------------------------------------------------------------| -------------| -| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid)| -< | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal)| +| Icon | Application | +|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) | +| < | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) | Developed By ------- diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 995ca04..41335c7 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -54,6 +54,13 @@ public void onClick(View v) { } }); + findViewById(R.id.action_remove_format).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.removeFormat(); + } + }); + findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/sample/src/main/res/drawable-xxhdpi/remove_format.png b/sample/src/main/res/drawable-xxhdpi/remove_format.png new file mode 100644 index 0000000000000000000000000000000000000000..a8ffe48048b91a3954356484e76ddd52c1105e6c GIT binary patch literal 2551 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 literal 0 HcmV?d00001 diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index b097e32..ea159ba 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -29,6 +29,14 @@ android:contentDescription="@null" android:src="@drawable/redo" /> + + Date: Sat, 31 Dec 2022 20:04:28 +0100 Subject: [PATCH 035/136] add remove_format to sample app --- README.md | 11 ++++++----- .../java/jp/wasabeef/sample/MainActivity.java | 13 ++++++++++--- .../main/res/drawable-xxhdpi/remove_format.png | Bin 0 -> 2551 bytes sample/src/main/res/layout/activity_main.xml | 8 ++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/remove_format.png diff --git a/README.md b/README.md index 8229480..4e44926 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Supported Functions ![Toolbar](./art/demo.gif) +- [x] (new?) Remove Format - [x] Bold - [x] Italic - [x] Subscript @@ -159,7 +160,7 @@ editor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/twitte **Text Change Listener** ```java RichEditor editor = (RichEditor) findViewById(R.id.editor); -editor. setOnTextChangeListener(new RichEditor.OnTextChangeListener() { +editor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { // Do Something @@ -180,10 +181,10 @@ Applications using RichEditor for Android Please [ping](mailto:dadadada.chop@gmail.com) me or send a pull request if you would like to be added here. -| Icon | Application| -|----------------------------------------------------------------------------------------------------------------------------------------------------| -------------| -| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid)| -< | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal)| +| Icon | Application | +|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) | +| < | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) | Developed By ------- diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 995ca04..c05a4b2 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -54,10 +54,17 @@ public void onClick(View v) { } }); - findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { + findViewById(R.id.action_remove_format).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + mEditor.removeFormat(); + } + }); + findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +/* mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { @Override public void onDataReceived(String value) { @@ -69,8 +76,8 @@ public void onClick(View v) { mEditor.getHtml(); - - //mEditor.setBold(); +*/ + mEditor.setBold(); } }); diff --git a/sample/src/main/res/drawable-xxhdpi/remove_format.png b/sample/src/main/res/drawable-xxhdpi/remove_format.png new file mode 100644 index 0000000000000000000000000000000000000000..a8ffe48048b91a3954356484e76ddd52c1105e6c GIT binary patch literal 2551 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 literal 0 HcmV?d00001 diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index b097e32..ea159ba 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -29,6 +29,14 @@ android:contentDescription="@null" android:src="@drawable/redo" /> + + Date: Fri, 6 Jan 2023 14:58:10 +0100 Subject: [PATCH 036/136] add Checkbox without ID --- richeditor/src/main/assets/rich_editor.js | 32 +++++++++---------- .../jp/wasabeef/richeditor/RichEditor.java | 10 +++--- .../java/jp/wasabeef/sample/MainActivity.java | 4 +-- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index ad5471d..3e1b9a9 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -254,27 +254,27 @@ RE.setUnorderedList = function() { document.execCommand('insertUnorderedList', false, null); }; -function createCheckbox(id) { - var el = document.querySelector("input[name='" + id + "']"); +function createCheckbox(node) { var d = document.createElement("input"); d.setAttribute("type", "checkbox"); - d.setAttribute("name", id); - if(el.checked) { - d.setAttribute("checked", null); + if(node.checked) { + d.setAttribute("checked", true); } - el.parentNode.insertBefore(d, el); - el.parentNode.removeChild(el); - el = document.querySelector("input[name='" + id + "']"); - el.addEventListener("change", function() {createCheckbox(id);}); + d.addEventListener("change", function() {createCheckbox(this);}); + + node.parentNode.insertBefore(d, node); + node.parentNode.removeChild(node); }; -RE.setCheckbox = function(id) { +RE.setCheckbox = function() { + var elements = document.querySelectorAll(":hover"); var el = document.createElement("input"); + RE.insertHTML(' '); el.setAttribute("type", "checkbox"); - el.setAttribute("name", id); - RE.insertHTML(" " + el.outerHTML + " "); - el = document.querySelector("input[name='" + id + "']"); - el.addEventListener("change", function() {createCheckbox(id);}); + el.addEventListener("change", function() {createCheckbox(this);}); + elements[elements.length - 1].appendChild(el); + el.focus(); //sets focus to element + //focus should be behind the box...but i don't get it RE.callback("input"); }; @@ -340,7 +340,7 @@ RE.insertYoutubeVideo = function(url, width="100%", height="100%") { RE.insertCollapsibleSection = function(section, content) { var d = document.createElement("button"); d.setAttribute("class", "collapsible"); - d.innerHTML = section; + d.innerHTML = " " + section; d.addEventListener("click", function() { this.classList.toggle("active"); var content = this.nextElementSibling; @@ -354,7 +354,7 @@ RE.insertCollapsibleSection = function(section, content) { d=elements[elements.length - 1].appendChild(d); var e=document.createElement("div"); e.setAttribute("class", "content"); - e.innerHTML = '

' + content + '

'; + e.innerHTML = '

' + content + '

'; elements[elements.length - 1].appendChild(e); // next empty element diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index a265775..7bfb7db 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -547,12 +546,11 @@ public void insertLink(String href, String title) { exec("javascript:RE.insertLink('" + href + "', '" + title + "');"); } - public String insertCheckbox(String uuid) { - if (uuid.isEmpty()) - uuid = UUID.randomUUID().toString(); + public void insertCheckbox() { + //if (uuid.isEmpty()) + // uuid = UUID.randomUUID().toString(); exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.setCheckbox('"+ uuid +"')"); - return uuid; + exec("javascript:RE.setCheckbox()"); } public void focusEditor() { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index c05a4b2..b3b6162 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -32,7 +32,7 @@ protected void onCreate(Bundle savedInstanceState) { //mEditor.setInputEnabled(false); mPreview = (TextView) findViewById(R.id.preview); - mEditor.setHTML_asCallBack(true); + //mEditor.setHTML_asCallBack(true); mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { @@ -312,7 +312,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_checkbox).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertCheckbox(""); + mEditor.insertCheckbox(); } }); From d7e617791e8eb51b41ef5881c4fbca1ac4500ca8 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 7 Jan 2023 19:40:52 +0100 Subject: [PATCH 037/136] fix insertLink add insertLinkSelection --- richeditor/src/main/assets/rich_editor.js | 6 ++++++ .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 4 ++-- sample/src/main/java/jp/wasabeef/sample/MainActivity.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 3e1b9a9..f9472f3 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -369,6 +369,12 @@ RE.insertHTML = function(html) { }; RE.insertLink = function(url, text, title) { + RE.restorerange(); + document.execCommand("insertHTML",false,""+text+""); + RE.callback(); +}; + +RE.insertLinkSelection = function(url, text, title) { RE.restorerange(); var sel = document.getSelection(); if (sel.toString().length == 0) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 7bfb7db..d5d0e51 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -541,9 +541,9 @@ public void insertYoutubeVideo(String url, int width, int height) { exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "', '" + height + "');"); } - public void insertLink(String href, String title) { + public void insertLink(String href, String text, String title) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertLink('" + href + "', '" + title + "');"); + exec("javascript:RE.insertLink('" + href + "', '" + text + "', '" + title + "');"); } public void insertCheckbox() { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index b3b6162..f828583 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -305,7 +305,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_link).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertLink("https://github.com/wasabeef", "wasabeef"); + mEditor.insertLink("https://github.com/wasabeef", "https://github.com/wasabeef", "wasabeef"); } }); From 7aec391015847a17943bf0a2aeef720c43d40b84 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 7 Jan 2023 20:18:09 +0100 Subject: [PATCH 038/136] for insertImage & Video, width is set automatically if nothing given --- richeditor/src/main/assets/rich_editor.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index f9472f3..e8109ed 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -306,7 +306,10 @@ RE.insertImage = function(url, alt="", width="", height="" ) { var img = document.createElement('img'); img.setAttribute("src", url); if (alt != "") img.setAttribute("alt", alt); - if (width != "") img.setAttribute("width", width); + if (width != "") + img.setAttribute("width", width); + else + img.setAttribute("width", window.innerWidth); if (height != "") img.setAttribute("height", height); img.onload = RE.updateHeight; @@ -319,7 +322,10 @@ RE.insertVideo = function(url, width="", height="") { video.setAttribute("src", url); video.controls = true; video.muted = false; - if (width != "") video.setAttribute("width", width); + if (width != "") + video.setAttribute("width", width); + else + video.setAttribute("width", window.innerWidth); if (height != "") video.setAttribute("height", height); video.onload = RE.updateHeight; From 1d7def0ef473f26cfc1e0255853d76898d09d0fa Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 13 Jan 2023 17:27:04 +0100 Subject: [PATCH 039/136] add listener to checkbox and section after reload --- richeditor/src/main/assets/rich_editor.js | 36 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index e8109ed..4351c40 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -254,6 +254,15 @@ RE.setUnorderedList = function() { document.execCommand('insertUnorderedList', false, null); }; +RE.fixCheckbox = function() { +var coll = document.querySelectorAll('input[type=checkbox]'); +var i; + +for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("change", function() {createCheckbox(this);}); + } +} + function createCheckbox(node) { var d = document.createElement("input"); d.setAttribute("type", "checkbox"); @@ -343,19 +352,30 @@ RE.insertYoutubeVideo = function(url, width="100%", height="100%") { RE.insertHTML(html); } -RE.insertCollapsibleSection = function(section, content) { - var d = document.createElement("button"); - d.setAttribute("class", "collapsible"); - d.innerHTML = " " + section; - d.addEventListener("click", function() { - this.classList.toggle("active"); - var content = this.nextElementSibling; +RE.fixCollapsibleSection = function() { +var coll = document.getElementsByClassName("collapsible"); +var i; + +for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("click", function() {CollapsibleSection(this);}); + } +} + +function CollapsibleSection(node) { + node.classList.toggle("active"); + var content = node.nextElementSibling; if (content.style.maxHeight){ content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } - }); + } + +RE.insertCollapsibleSection = function(section, content) { + var d = document.createElement("button"); + d.setAttribute("class", "collapsible"); + d.innerHTML = " " + section; + d.addEventListener("click", function() {CollapsibleSection(this);}); var elements = document.querySelectorAll(":hover"); d=elements[elements.length - 1].appendChild(d); var e=document.createElement("div"); From 974118daa5ba7348afa42ccf1a673da4f523c812 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 13 Jan 2023 17:28:31 +0100 Subject: [PATCH 040/136] add listener to checkbox and section after reload --- richeditor/src/main/assets/style.css | 2 +- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index bc0c05b..7d2ab0e 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -93,7 +93,7 @@ td{padding:5px 10px; height:35px;} border: none; text-align: left; outline: none; - font-size: 15px; + font-size: 22px; } .active, .collapsible:hover { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index d5d0e51..bee71a5 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -209,6 +209,8 @@ public void setHtml(String contents) { } try { exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');"); + exec("javascript:RE.fixCheckbox();"); + exec("javascript:RE.fixCollapsibleSection();"); } catch (UnsupportedEncodingException e) { // No handling } @@ -547,10 +549,8 @@ public void insertLink(String href, String text, String title) { } public void insertCheckbox() { - //if (uuid.isEmpty()) - // uuid = UUID.randomUUID().toString(); exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.setCheckbox()"); + exec("javascript:RE.setCheckbox();"); } public void focusEditor() { From 11963d7583424cb8e3c30b473136c3914799c545 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 13 Jan 2023 19:52:20 +0100 Subject: [PATCH 041/136] insertImage and InsertVideo width and height as Strings * width="auto" use always 100% of page width * for smaller images just put them in a table cell * use px or % --- richeditor/src/main/assets/rich_editor.js | 22 +++++---- richeditor/src/main/assets/style.css | 5 ++ .../jp/wasabeef/richeditor/RichEditor.java | 48 ++++++------------- .../java/jp/wasabeef/sample/MainActivity.java | 8 ++-- 4 files changed, 36 insertions(+), 47 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 4351c40..4bc40be 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -315,13 +315,13 @@ RE.insertImage = function(url, alt="", width="", height="" ) { var img = document.createElement('img'); img.setAttribute("src", url); if (alt != "") img.setAttribute("alt", alt); - if (width != "") - img.setAttribute("width", width); - else - img.setAttribute("width", window.innerWidth); - if (height != "") img.setAttribute("height", height); + if (width == "auto") + img.setAttribute("id", "responsive-image"); + else if (width != "") { + img.setAttribute("width", width); + if (height != "") img.setAttribute("height", height); + } img.onload = RE.updateHeight; - RE.insertHTML(img.outerHTML); RE.callback("input"); }; @@ -331,11 +331,13 @@ RE.insertVideo = function(url, width="", height="") { video.setAttribute("src", url); video.controls = true; video.muted = false; - if (width != "") + + if (width == "auto") + video.setAttribute("width", "responsive-image"); + else if (width != "") { video.setAttribute("width", width); - else - video.setAttribute("width", window.innerWidth); - if (height != "") video.setAttribute("height", height); + if (height != "") video.setAttribute("height", height); + } video.onload = RE.updateHeight; RE.insertHTML(video.outerHTML); diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index 7d2ab0e..2064e03 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -74,6 +74,11 @@ input[type=checkbox] { margin-right: 9px; } +#responsive-image { + width: 100%; + height: auto; +} + video { width: 100% !important; height: auto !important; diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index bee71a5..abfa055 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -455,38 +455,21 @@ public void insertCollapsibleSection(String section, String content) { exec("javascript:RE.insertCollapsibleSection('"+section+"', '"+content+"');"); } - public void insertImage(String url, String alt) { - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + url + "', '" + alt + "');"); - } - - /** - * the image according to the specific width of the image automatically - * - * @param url - * @param alt - * @param width - */ - public void insertImage(String url, String alt, int width) { - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "');"); - } - /** - * {@link RichEditor#insertImage(String, String)} will show the original size of the image. + * {@link RichEditor#insertImage(String, String, String, String)} will show the original size of the image. * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. * * @param url * @param alt - * @param width + * @param width Width of the Image; auto=100% page width * @param height */ - public void insertImage(String url, String alt, int width, int height) { + public void insertImage(String url, String alt, String width, String height) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "');"); } - public void insertImageAsBase64(Uri imageURI, String alt) { + public void insertImageAsBase64(Uri imageURI, String alt,String width, String height) { InputStream inputStream= null; try { inputStream = getContext().getContentResolver().openInputStream(imageURI); @@ -504,21 +487,20 @@ public void insertImageAsBase64(Uri imageURI, String alt) { String format="png"; String tag = "data:image/" + format + ";charset=utf-8;base64,"; exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "',"+alt+");"); + exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "','"+ alt + "','" + width + "', '" + height + "');"); //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); } - public void insertVideo(String url) { - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertVideo('" + url + "');"); - } - - public void insertVideo(String url, int width) { - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertVideo('" + url + "', '" + width + "');"); - } - - public void insertVideo(String url, int width, int height) { + /** + * {@link RichEditor#insertVideo(String, String, String)} will show the original size of the video. + * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. + * + * @param url + * @param alt + * @param width Width of the video; auto=100% page width + * @param height + */ + public void insertVideo(String url, String width, String height) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertVideo('" + url + "', '" + width + "', '" + height + "');"); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index f828583..4164278 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -275,9 +275,9 @@ public void onClick(View v) { "://" + getResources().getResourcePackageName(R.drawable.insert_image) + '/' + getResources().getResourceTypeName(R.drawable.insert_image) + '/' + getResources().getResourceEntryName(R.drawable.bg_color); // image="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Hyoscyamus_niger_0003.JPG/449px-Hyoscyamus_niger_0003.JPG"; - image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; - mEditor.insertImageAsBase64(Uri.parse(image),"alt"); - //mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", 320); + // image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; + mEditor.insertImageAsBase64(Uri.parse(image),"alt","auto",""); + //mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "auto",""); } }); @@ -298,7 +298,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_video).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertVideo("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_10MB.mp4", 360); + mEditor.insertVideo("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_10MB.mp4", "360",""); } }); From 29f0c97aab93280c4daa6f2af7b22621327ac9db Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 13 Jan 2023 21:17:24 +0100 Subject: [PATCH 042/136] * add better youtube example --- richeditor/src/main/assets/rich_editor.js | 2 +- .../java/jp/wasabeef/sample/MainActivity.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 4bc40be..505996c 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -350,7 +350,7 @@ RE.insertAudio = function(url, alt) { } RE.insertYoutubeVideo = function(url, width="100%", height="100%") { - var html = '
' + var html = '
' RE.insertHTML(html); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 4164278..05bbdda 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -284,8 +284,29 @@ public void onClick(View v) { findViewById(R.id.action_insert_youtube).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertYoutubeVideo("https://www.youtube.com/embed/pS5peqApgUA"); + // 1. get the selected text via callback + // 2. make the embedded video + mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { + @Override public void onDataReceived(String value) { + if(!value.isEmpty()) { + if(value.startsWith("https://www.youtube.com")) + value = value.replace("watch?v=","embed/"); + + // https://www.youtube.com/watch?v=3AeYHDZ2riI + // https://www.youtube.com/embed/3AeYHDZ2riI + + mEditor.insertYoutubeVideo(value); + } + else + mEditor.insertHTML("Select a youtube link"); + } + }); + mEditor.getSelectedText(); + //mEditor.insertYoutubeVideo("https://www.youtube.com/embed/pS5peqApgUA"); } + + + }); findViewById(R.id.action_insert_audio).setOnClickListener(new View.OnClickListener() { From 43cbea544c34055550ecd92b5cee897140089369 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 14 Jan 2023 22:50:07 +0100 Subject: [PATCH 043/136] * add fontFamily support --- README.md | 5 +-- richeditor/src/main/assets/rich_editor.js | 34 ++++++++++++++++++ .../jp/wasabeef/richeditor/RichEditor.java | 29 ++++++++++++--- .../java/jp/wasabeef/sample/MainActivity.java | 20 ++++------- .../main/res/drawable-xxhdpi/font_cursive.png | Bin 0 -> 3220 bytes sample/src/main/res/layout/activity_main.xml | 8 +++++ 6 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/font_cursive.png diff --git a/README.md b/README.md index 4e44926..a7e3e84 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Supported Functions - [x] (new) Text Color (String) - [x] Text Background Color - [x] (new) Text Background Color (String) +- [x] Font Family - [x] Text Font Size - [x] Unordered List (Bullets) - [x] Ordered List (Numbers) @@ -80,10 +81,6 @@ Attribute change of editor - [x] State Callback - [x] (new) setHTML_asCallBack (don't encode & copy the complete HTML page on every change by callback) -**Milestone** - -- [ ] Font Family - Demo --- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 505996c..2d3ae47 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -233,6 +233,40 @@ RE.setTextBackgroundColor = function(color) { document.execCommand("styleWithCSS", null, false); }; +RE.setFontFamily = function(fontName){ + document.execCommand('fontName', false, fontName); +} + +RE.getFontFamily = function getFontFamily() { + var arr = []; + /* + sounds good - doesn't work + any ideas? + var it = document.fonts.entries(); + + var arr = []; + let done = false; + + while (!done) { + const font = it.next(); + if (!font.done) { + arr.push(font.value[0].family); + } else { + done = font.done; + } + } + */ + arr.push('sans-serif'); + arr.push('monospace'); + arr.push('sans-serif'); + arr.push('serif'); + arr.push('cursive'); + arr.push('fantasy'); + // converted to set then arr to filter repetitive values + return [...new Set(arr)]; +} + + RE.setHeading = function(heading) { var sel = document.getSelection().getRangeAt(0).startContainer.parentNode; document.execCommand('formatBlock', false, sel.tagName === `H${heading}` ? '

' : ``); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index abfa055..d59fa90 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -137,9 +137,20 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { e.printStackTrace(); } if (!"null".equals(unescaped)) { - unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes - .replace("\\\\", "\\") // unescape \\ -> \ - .replace("\\\"", "\""); // unescape \" -> " + + if(unescaped.startsWith("[")) { + // Array + unescaped = unescaped.substring(2, unescaped.length() - 2) // remove wrapping quotes + .replace("\\\\", "\\") // unescape \\ -> \ + .replace("\\\"", "\"") // unescape \" -> " + .replace("\",\"", ";") ; // replace "," -> ; + + } else { + unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes + .replace("\\\\", "\\") // unescape \\ -> \ + .replace("\\\"", "\""); // unescape \" -> " + + } } if (mJSDataListener != null) { @@ -394,6 +405,14 @@ public void setTextBackgroundColor(String color) { exec("javascript:RE.setTextBackgroundColor('" + color + "');"); } + public void setFontFamily(String fontFamily) { + exec("javascript:RE.setFontFamily('" + fontFamily + "');"); + } + + public void getFontFamily() { + requestJSData("javascript:RE.getFontFamily();"); + } + public void setFontSize(int fontSize) { if (fontSize > 7 || fontSize < 1) { Log.e("RichEditor", "Font size should have a value between 1-7"); @@ -443,12 +462,12 @@ public void setNumbers() { public void insertHTML(String text) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertHTML('" + text + "')"); + exec("javascript:RE.insertHTML('" + text + "');"); } public void insertHR_Line() { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertHTML('


')"); + exec("javascript:RE.insertHTML('
');"); } public void insertCollapsibleSection(String section, String content) { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 05bbdda..1728509 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -64,19 +64,6 @@ public void onClick(View v) { findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { -/* - - mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { - @Override public void onDataReceived(String value) { - String temp; - if(!value.isEmpty()) - temp=value; - } - }); - - mEditor.getHtml(); - -*/ mEditor.setBold(); } }); @@ -116,6 +103,13 @@ public void onClick(View v) { } }); + findViewById(R.id.action_font_cursive).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.setFontFamily("cursive"); + } + }); + findViewById(R.id.action_heading1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/sample/src/main/res/drawable-xxhdpi/font_cursive.png b/sample/src/main/res/drawable-xxhdpi/font_cursive.png new file mode 100644 index 0000000000000000000000000000000000000000..70adff5c4b16d4f8c4a1839295ac0e5b915fad9d GIT binary patch literal 3220 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 F{{_)!<6Zy& literal 0 HcmV?d00001 diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index ea159ba..fe298e9 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -85,6 +85,14 @@ android:contentDescription="@null" android:src="@drawable/underline" /> + + Date: Sat, 14 Jan 2023 22:50:52 +0100 Subject: [PATCH 044/136] * InsertVideo gets attribute alt as well --- richeditor/src/main/assets/rich_editor.js | 3 ++- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 6 +++--- sample/src/main/java/jp/wasabeef/sample/MainActivity.java | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 2d3ae47..4bcdc29 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -360,11 +360,12 @@ RE.insertImage = function(url, alt="", width="", height="" ) { RE.callback("input"); }; -RE.insertVideo = function(url, width="", height="") { +RE.insertVideo = function(url, alt="", width="", height="") { var video = document.createElement('video'); video.setAttribute("src", url); video.controls = true; video.muted = false; + if (alt != "") video.setAttribute("alt", alt); if (width == "auto") video.setAttribute("width", "responsive-image"); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index d59fa90..31c74f0 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -511,7 +511,7 @@ public void insertImageAsBase64(Uri imageURI, String alt,String width, String he } /** - * {@link RichEditor#insertVideo(String, String, String)} will show the original size of the video. + * {@link RichEditor#insertVideo(String, String, String, String)} will show the original size of the video. * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. * * @param url @@ -519,9 +519,9 @@ public void insertImageAsBase64(Uri imageURI, String alt,String width, String he * @param width Width of the video; auto=100% page width * @param height */ - public void insertVideo(String url, String width, String height) { + public void insertVideo(String url, String alt, String width, String height) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertVideo('" + url + "', '" + width + "', '" + height + "');"); + exec("javascript:RE.insertVideo('" + url + "', '" + alt + "', '" + width + "' '" + height + "');"); } public void insertAudio(String url) { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 1728509..62e021c 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -313,7 +313,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_video).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertVideo("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_10MB.mp4", "360",""); + mEditor.insertVideo("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_10MB.mp4","TestVideo" ,"360",""); } }); From 5a441a4dcf5d43ee6104f1153c95dbb4013a7e0b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 16 Jan 2023 17:25:05 +0100 Subject: [PATCH 045/136] * support for LoadFont() --- README.md | 2 ++ richeditor/src/main/assets/Alita Brush.ttf | Bin 0 -> 57912 bytes richeditor/src/main/assets/rich_editor.js | 18 ++++++++++++------ .../jp/wasabeef/richeditor/RichEditor.java | 9 +++++---- .../java/jp/wasabeef/sample/MainActivity.java | 6 ++++-- 5 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 richeditor/src/main/assets/Alita Brush.ttf diff --git a/README.md b/README.md index a7e3e84..cfcefee 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ Attribute change of editor - [x] Height - [x] Placeholder - [x] Load CSS +- [x] (new) Load Font +- [x] (new) getFontFamily - [x] State Callback - [x] (new) setHTML_asCallBack (don't encode & copy the complete HTML page on every change by callback) diff --git a/richeditor/src/main/assets/Alita Brush.ttf b/richeditor/src/main/assets/Alita Brush.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1dc4ac5a9332cce73752d82c52e7de44ec967704 GIT binary patch literal 57912 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 literal 0 HcmV?d00001 diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 4bcdc29..f069f54 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -237,12 +237,20 @@ RE.setFontFamily = function(fontName){ document.execCommand('fontName', false, fontName); } +RE.LoadFont = function LoadFont(name, url) { + let font = new FontFace(name, 'url("'+ url +'")'); + font.load().then(function(loadedFont) + { + document.fonts.add(loadedFont); + //do something after the font is loaded + }).catch(function(error) { + RE.insertHTML(error) + // error occurred + }); +} RE.getFontFamily = function getFontFamily() { var arr = []; - /* - sounds good - doesn't work - any ideas? - var it = document.fonts.entries(); + var it = document.fonts.entries(); var arr = []; let done = false; @@ -255,8 +263,6 @@ RE.getFontFamily = function getFontFamily() { done = font.done; } } - */ - arr.push('sans-serif'); arr.push('monospace'); arr.push('sans-serif'); arr.push('serif'); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 31c74f0..a9b01c2 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -61,17 +61,14 @@ public interface onJSDataListener { } public interface OnTextChangeListener { - - void onTextChange(String text); + void onTextChange(String text); } public interface OnDecorationStateListener { - void onStateChangeListener(String text, List types); } public interface AfterInitialLoadListener { - void onAfterInitialLoad(boolean isReady); } @@ -409,6 +406,10 @@ public void setFontFamily(String fontFamily) { exec("javascript:RE.setFontFamily('" + fontFamily + "');"); } + public void LoadFont(String name, String url) { + exec("javascript:RE.LoadFont('" + name + "','"+url+"');"); + } + public void getFontFamily() { requestJSData("javascript:RE.getFontFamily();"); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 62e021c..f2cca68 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -30,7 +30,7 @@ protected void onCreate(Bundle savedInstanceState) { //mEditor.setBackground("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"); mEditor.setPlaceholder("Insert text here..."); //mEditor.setInputEnabled(false); - + mEditor.LoadFont("Alita Brush","Alita Brush.ttf"); mPreview = (TextView) findViewById(R.id.preview); //mEditor.setHTML_asCallBack(true); mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @@ -106,7 +106,9 @@ public void onClick(View v) { findViewById(R.id.action_font_cursive).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setFontFamily("cursive"); + // mEditor.setFontFamily("Alita Brush"); + mEditor.setFontFamily("cursive"); + // mEditor.getFontFamily(); } }); From 9fec3f3ea3d1205e2515648e19217960844a3974 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 16 Jan 2023 17:28:26 +0100 Subject: [PATCH 046/136] * update How to use --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cfcefee..9e93252 100644 --- a/README.md +++ b/README.md @@ -95,13 +95,19 @@ How do I use it? ##### Gradle ```groovy -repositories { - mavenCentral() -} +~~repositories {~~ +~~ mavenCentral()~~ +~~}~~ dependencies { - implementation 'jp.wasabeef:richeditor-android:2.0.0' + implementation files('../../richeditor-android/richeditor/build/outputs/aar/richeditor-debug.aar') + ~~implementation 'jp.wasabeef:richeditor-android:2.0.0'~~ } + +settings.gradle: +includeBuild('../richeditor-android') + + ``` ### Default Setting for Editor --- From 70251b74a5f41ace7304f5f150ede6953305261d Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 16 Jan 2023 17:30:52 +0100 Subject: [PATCH 047/136] * update How to use --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9e93252..6348e36 100644 --- a/README.md +++ b/README.md @@ -94,17 +94,23 @@ How do I use it? ### Setup ##### Gradle -```groovy + ~~repositories {~~ -~~ mavenCentral()~~ + ~~mavenCentral()~~ +~~}~~ + +~~dependencies {~~ + ~~implementation 'jp.wasabeef:richeditor-android:2.0.0'~~ ~~}~~ +```groovy + dependencies { implementation files('../../richeditor-android/richeditor/build/outputs/aar/richeditor-debug.aar') - ~~implementation 'jp.wasabeef:richeditor-android:2.0.0'~~ } -settings.gradle: +settings.gradle + includeBuild('../richeditor-android') From 4d13be2ca3eb1689409c6f4f293c7acb210e9906 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 19 Jan 2023 08:49:29 +0100 Subject: [PATCH 048/136] * update gradle 7.4.0 --- build.gradle | 4 ++-- richeditor/build.gradle | 1 + richeditor/src/main/AndroidManifest.xml | 2 +- sample/build.gradle | 1 + sample/src/main/AndroidManifest.xml | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index b27694b..4763e28 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,10 @@ buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:7.4.0' // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' diff --git a/richeditor/build.gradle b/richeditor/build.gradle index c4fb5c3..d8a190c 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -7,6 +7,7 @@ android { minSdkVersion MIN_SDK_VERSION as int targetSdkVersion TARGET_SDK_VERSION as int } + namespace 'jp.wasabeef.richeditor' } diff --git a/richeditor/src/main/AndroidManifest.xml b/richeditor/src/main/AndroidManifest.xml index 78a9b04..cc947c5 100644 --- a/richeditor/src/main/AndroidManifest.xml +++ b/richeditor/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/sample/build.gradle b/sample/build.gradle index 420168f..23d5591 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -29,6 +29,7 @@ android { signingConfig signingConfigs.release } } + namespace 'jp.wasabeef.sample' } repositories { diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index c0885ba..4cc9c25 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + > From 5711977fcd9fd856184e98cb413e071a6c953819 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 19 Jan 2023 09:50:52 +0100 Subject: [PATCH 049/136] * new icon for cursive --- .../main/res/drawable-xxhdpi/font_cursive.png | Bin 3220 -> 12760 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sample/src/main/res/drawable-xxhdpi/font_cursive.png b/sample/src/main/res/drawable-xxhdpi/font_cursive.png index 70adff5c4b16d4f8c4a1839295ac0e5b915fad9d..9f526204d90c6fa47971d4e2092d7cd32c6ddf04 100644 GIT binary patch literal 12760 zcmeHtbyQp1)^BikC=`lADH2=~iaQi{_W;2HBuIgl(&ApA6!#*fKyjC%1=`~7P~1v! zD=+k%d+s^o`^I?Vj`7}qHyL|pues*@tvP>d&Xv8h60WJPNPtU?3jhEJl$GSPk)LsQ z2R0`1yrHmC4**aF`05%Ww5_}u+&o}*P-h4O;;9>i0pbI-0|0zxO4FcTrXrO=w>A_l z=wCWLcr!;I`wSfLxJ8mHYb8M>hpped-v`(#D9E8s+TAV j~ucsNdX={mZCO@4LV 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 literal 3220 zcmZ`+XH-+!8ikM$Ae0y|NQZ<@q{M<0NeDqekRpOXA)o{h1?eb54WJ@55z!#h5yhc5 z3l@ryVg$so1Q9gShaxCN5O|lFAMdUA=AE_fy=(2e_de(Q&OPTl_o}m_jf9xIn1FzQ zgqW=m~Z~h{}mo!Kok!sbZ;E(~*LYYmDNMKJxnV@^S)h3atEfEDszMaH%%yC9u}^{eAv>{_`-}2K3p1({(#^XKyPY-F#HCGzC_6m--9-%?^0Xs^ zO8NKr_xbcPw;i_bi{HNsy?y(Z+SAj6H{2z@ci%q9*|TRs-QC?4HPDU^Xdw#K0hult zQ_V$?-EA~=r*{q*U`X}&*5+o`@^W-%Q$QajCdP!PDT+Uon_8P{Pl@{MR92qSVHljg zO!4Df*O{%UshJH94sO+Evs#tG9;8PklMRo_!wllPV+ZUaBgI@R1LKZ{&kdPWfv>V( z6&U*!Tg0=Ll{K;DI1#Vfx~l`7xF(sK;91g9*JHCPxazkhgh-+HFAIT8>}6(~7qo0ym^e*4m;9+UwD@UprZ)2L*-gIdik(oQEb zYjPgSR+>4hnpRpmiC)jo*Ll7+t%qo4w+4S?wW=zEjxY=@pKUCE41asyEqwS%On7^e zU`5tTQodSO7$IPqW6CmhE}bO3ialI1C*pkK#9;X>wGjWcCo6X(enp8_SyiQ@ew{aL zje^J{q^A6ElY!-k9Xol_9+c5@w>aT&>-=siIey9Q=jwv*fW@^O+$JMv0zn6D zI8HjOi^y^iXEMLt!%L}Hs9RbKWt@vxABKw&4U0kxgM{?5afj| zO}jP5hln(vd5s#-m-miafbfPP2wk{^ay#hKltamN~Gl`ynE@Y=U7DfZ_-W6VtBr*+xS~vXop##)_r>OWVn2}VG zX)|3xKoBoL^ms<_U-AF#2PEJhO|mI)ZDZr(&(`PK8lOG0_|e~|lCWx7bRZ1%L$;>y zlfxVe1OL{B2UcI6qX`fjC`m`#SnQcCGAQ4`u@Okh*_h3e`ELW-$%`w z3iVa%V=(F;nMn{(!cLJy=g^foFJOlA^71OAwu#;ldGm{gfxgUAt1GrDr`th-&&5&` z3xa3b7q}KL02PLI86wsN3M8pssmIGBS!&xrxCpG`6jibFKj8DQR4CQ=8~V}31yo=F zRDJJC*!=LpfnFdx(fvEl!$x{>Nj$i~0)$BbrT$AZ@!qCaI8tdc5Q*>Rt@Z ziliz58-@QfOgkn$`MTU@ag?1K-d|$bmn8%nr5%G$4&1RX?Sp5j;K=@desm)Nz~&dG zzsmLQXr|nr$3KV?Km-Xglf8vz;T_2kF9b6g5}q~!UR(RK&dP~r*tZ9{tx)fuC{9%V z&O2CsDC?S@do``VIOGOYQjzAJ@YB!sa>(fR zATiF2nv)N%b=YZ+_ZHgsib`eNuc}fDj+Hi#d}DrI{FhF@R&g9bSj%H|ydZ@2GifdX zRxT~6V&RajAe1PUI-h0?)$+JF+wz|E^KQCgv(71 zu-jR5H2YEHO2|xXr$WdR%WReHPMK>3DPN=H6%^PpKx!{HXJ|nn5a6Twb{GG7ZRt-+ z(i85&S0>x!dR`tqdI99Li_PV#$EQ&fA)PBYM#`vP=v0R}G;Sk_r%xuf#leNP#74)r zhKB`iDsv+aM9=IBlr`8N^Z}ne0{Nu}C-=RwT*N-iN^;tDDEW$G{wyC-yD#7O!}hz- zJxP@Djufa74vT;!!bW?>5^?nr6OPzuuNNbrM;rSOc;xR7mX~YO=Z8?+^Y;X>l8lr* z+oE?z-W^eVpwCaFBK19Og|ntgnm%fMYTp8V@gD`IgVk;nTxu}f?G_useN5egfL`7- z&`M!8v-h2QM{AhYtWtA+p0IIk?%km$9mh{Chb{|NslgezL<_kW$NZ-T?ocunX{Mkr zLQ^d*EfiH(`s2r@TE>oM=qNB~RmglOYCm*u9@=;jC#C)_eyHuu()b|M|`c0Yb7mW)(@fIPb!sC=H;h4lStanw>D!DL~L>a z6R4h}ieK>+cF#ea5^>TMpW*LEn0^6ue>>mLbWT?rv_@@!D>;>#=P$ELl@m2g$IyNb6Sq z-SiWsW($~KZ=^rh$>@7Ob4Xr99k2Ba^L_e8&fPyiM(9$n46o;DC{2(6Yd&f|BG*SN zEZnW9r#JTIu9MvvvcP=fyPA_)>nrn4YjX&9|1G%bOW9O=&>fvM-Gs7TrK@%QN)5DO?ZwX9OZ~bVP@Z=$MKt$&@HND@yMkj{4QI!6Hgz+z zV|IYuy}SzRGja~-XBYc~C22?{c&kNTW+Cz)Yr>Hy8H)*3yYh>Qp1DUx!d=nrC<(oI zCwf7_N3y&7JM!`4?`x5DVNhnrLa1kxfqpWk+LN$&kGolwprX@^-!?(P#p?1Hi{A!K zJY7mmn^EQ(w|Zi4{Q4F5D2RuRnd~p^?`|8ucSTBtlLD2xyqpmmJ#HkO#hGm7OwUiR zfJ&RJF0%&mmU7(Qz1+p!$mbtV@8oj13-=?oju!rUu(qPq?OIyHY@Q0lVzJ3Uap{Qp zJ`Nd4+}ijIWG%%eM_HoCG)kA`?X41Y=FBQ?b%mX)m12{vD0-gPsIfX6I}e%YEmXkh z>Wa-Whc1AC<7J8&i|FTi2iv)?m{7XMDw@^bae!$IGc zz!LuEyazZa4UWqb?H`@LF-~6>={xK|uoNa?(9)EYOqyHgSOe#ph%tW+_Q?dp6&Br) zU;l1cUlb;FZip_}h}Xm+P0^Gw(U@w24TfH?+V!WdepY$Y!?O}(AJ1<23zQ@bO|-G$ z#X_bz-7iW!1Dn)~y~^ZtHSvjhzjryD{=)z7Htn(@)l=kU>UGps8u;4~u(Ng~))IV@ F{{_)!<6Zy& From d94644d3df12a4016b36a00f289ad08a3abdf6ee Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 21 Jan 2023 19:23:47 +0100 Subject: [PATCH 050/136] * fix README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6348e36..3ee14ec 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Supported Functions - [x] (new) Text Color (String) - [x] Text Background Color - [x] (new) Text Background Color (String) -- [x] Font Family +- [x] (new) Font Family - [x] Text Font Size - [x] Unordered List (Bullets) - [x] Ordered List (Numbers) From 7a35f57d547d14b2eca09c1d618981a427b4a9b2 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 23 Jan 2023 19:45:23 +0100 Subject: [PATCH 051/136] fix cursive icon --- .../main/res/drawable-xxhdpi/font_cursive.png | Bin 12760 -> 8087 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sample/src/main/res/drawable-xxhdpi/font_cursive.png b/sample/src/main/res/drawable-xxhdpi/font_cursive.png index 9f526204d90c6fa47971d4e2092d7cd32c6ddf04..0ce0580711b04a302eb71f77bb1b6166ef5fb93c 100644 GIT binary patch delta 4543 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 delta 9451 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 dHvJ8*s_%o}*n;-tzyC`hB{? Date: Mon, 23 Jan 2023 19:45:57 +0100 Subject: [PATCH 052/136] working on callback --- richeditor/src/main/assets/rich_editor.js | 86 +++++++++++++------ .../jp/wasabeef/richeditor/RichEditor.java | 3 +- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index f069f54..93d8359 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -96,16 +96,17 @@ RE.runCallbackQueue = function() { } setTimeout(function() { + var callback_text = "re-callback://" + RE.getCommandQueue(); if (RE.getHTML_asCallBack == true) { - window.location.href = "re-callback://"; + window.location.href = callback_text; } else { - window.location.href = "re-callback://" + RE.getHtml(); + window.location.href = callback_text + "HTML:" + RE.getHtml(); } }, 0); }; RE.getCommandQueue = function() { - var commands = JSON.stringify(RE.callbackQueue); + var commands = JSON.stringify( RE.callbackQueue ); RE.callbackQueue = []; return commands; }; @@ -294,14 +295,6 @@ RE.setUnorderedList = function() { document.execCommand('insertUnorderedList', false, null); }; -RE.fixCheckbox = function() { -var coll = document.querySelectorAll('input[type=checkbox]'); -var i; - -for (i = 0; i < coll.length; i++) { - coll[i].addEventListener("change", function() {createCheckbox(this);}); - } -} function createCheckbox(node) { var d = document.createElement("input"); @@ -316,13 +309,24 @@ function createCheckbox(node) { }; RE.setCheckbox = function() { - var elements = document.querySelectorAll(":hover"); - var el = document.createElement("input"); - RE.insertHTML(' '); + var el = document.createElement("input"); el.setAttribute("type", "checkbox"); - el.addEventListener("change", function() {createCheckbox(this);}); - elements[elements.length - 1].appendChild(el); - el.focus(); //sets focus to element + //el.setAttribute("name", id); + RE.insertHTML(" " + el.outerHTML + " "); + RE.setElementListener("checkbox"); + + + //el = document.querySelector("input[name='" + id + "']"); + + + +// var elements = document.querySelectorAll(":hover"); +// var el = document.createElement("input"); +// RE.insertHTML(' '); +// el.setAttribute("type", "checkbox"); +// el.addEventListener("change", function() {createCheckbox(this);}); +// elements[elements.length - 1].appendChild(el); +// el.focus(); //sets focus to element //focus should be behind the box...but i don't get it RE.callback("input"); }; @@ -395,14 +399,40 @@ RE.insertYoutubeVideo = function(url, width="100%", height="100%") { RE.insertHTML(html); } -RE.fixCollapsibleSection = function() { -var coll = document.getElementsByClassName("collapsible"); -var i; +RE.setElementListener = function(element) { +if (element=="section" || element=="") { + var coll = document.getElementsByClassName("collapsible"); + var i; + + for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("click", function() {CollapsibleSection(this);}); + } +} + +if (element=="checkbox" || element=="") { + var coll = document.querySelectorAll('input[type=checkbox]'); + var i; + + for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("change", function() {createCheckbox(this);}); + } +} + +if (element=="link" || element=="") { + var coll = document.querySelectorAll('a'); + var i; -for (i = 0; i < coll.length; i++) { - coll[i].addEventListener("click", function() {CollapsibleSection(this);}); + for (i = 0; i < coll.length; i++) { + coll[i].addEventListener("click", function() { + var ret = []; + ret.push(element); + ret.push(this.getAttribute("href")); + RE.callback(ret) ; + } + ); } } +} function CollapsibleSection(node) { node.classList.toggle("active"); @@ -418,7 +448,7 @@ RE.insertCollapsibleSection = function(section, content) { var d = document.createElement("button"); d.setAttribute("class", "collapsible"); d.innerHTML = " " + section; - d.addEventListener("click", function() {CollapsibleSection(this);}); + // d.addEventListener("click", function() {CollapsibleSection(this);}); var elements = document.querySelectorAll(":hover"); d=elements[elements.length - 1].appendChild(d); var e=document.createElement("div"); @@ -426,10 +456,15 @@ RE.insertCollapsibleSection = function(section, content) { e.innerHTML = '

' + content + '

'; elements[elements.length - 1].appendChild(e); + + // next empty element e=document.createElement("p"); e.innerHTML = '
'; elements[elements.length - 1].appendChild(e); + + RE.callback("input"); + RE.setElementListener("section"); } RE.insertHTML = function(html) { @@ -440,7 +475,8 @@ RE.insertHTML = function(html) { RE.insertLink = function(url, text, title) { RE.restorerange(); document.execCommand("insertHTML",false,"
"+text+""); - RE.callback(); + RE.setElementListener("link"); + RE.callback("input"); }; RE.insertLinkSelection = function(url, text, title) { @@ -458,7 +494,7 @@ RE.insertLinkSelection = function(url, text, title) { sel.removeAllRanges(); sel.addRange(range); } - RE.callback(); + RE.callback("input"); }; RE.prepareInsert = function() { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index a9b01c2..4c460c4 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -217,8 +217,7 @@ public void setHtml(String contents) { } try { exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');"); - exec("javascript:RE.fixCheckbox();"); - exec("javascript:RE.fixCollapsibleSection();"); + exec("javascript:RE.setElementListener();"); } catch (UnsupportedEncodingException e) { // No handling } From b31272173bf7678bd055fad629f6e0ba95418131 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 2 Feb 2023 20:52:31 +0100 Subject: [PATCH 053/136] remove setHTML_asCallBack --- README.md | 3 +-- richeditor/src/main/assets/rich_editor.js | 16 ++-------------- .../java/jp/wasabeef/richeditor/RichEditor.java | 13 ------------- .../java/jp/wasabeef/sample/MainActivity.java | 8 ++++++-- 4 files changed, 9 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 3ee14ec..4433ff8 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,7 @@ Attribute change of editor - [x] Load CSS - [x] (new) Load Font - [x] (new) getFontFamily -- [x] State Callback -- [x] (new) setHTML_asCallBack (don't encode & copy the complete HTML page on every change by callback) +- [x] State Callback Demo --- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 93d8359..170c2e7 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -25,15 +25,6 @@ var RE = {}; RE.editor = document.getElementById('editor'); -// in v2.0.0 each change, will raise a callback, which encodes and copy the complete HTML code back to java, -// this is very resource eating. -// with HTML_asCallBack=true, getHTML will be a normal callback -RE.getHTML_asCallBack = false; - -RE.setHTML_asCallBack = function(value) { - RE.getHTML_asCallBack = Boolean(value); -}; - // Not universally supported, but seems to work in iOS 7 and 8 document.addEventListener("selectionchange", function() { RE.backuprange(); @@ -97,11 +88,7 @@ RE.runCallbackQueue = function() { setTimeout(function() { var callback_text = "re-callback://" + RE.getCommandQueue(); - if (RE.getHTML_asCallBack == true) { - window.location.href = callback_text; - } else { - window.location.href = callback_text + "HTML:" + RE.getHtml(); - } + window.location.href = callback_text; }, 0); }; @@ -762,6 +749,7 @@ RE.blurFocus = function() { }; RE.removeFormat = function() { + document.execCommand('formatBlock', false, 'p'); document.execCommand('removeFormat', false, null); }; diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 4c460c4..119aa81 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -225,13 +225,8 @@ public void setHtml(String contents) { } public String getHtml() { - if(HTML_asCallBack) { requestJSData("RE.getHtml()"); return("data can only received by callback"); - } else { - // only for compatibility - return mContents; - } } /// Text representation of the data that has been input into the editor view, if it has been loaded. @@ -254,14 +249,6 @@ public boolean getSelectedHref() { } } - // in v2.0.0 each change, will raise a callback, which encodes and copy the complete HTML code back to java, - // this is very resource eating. - // with HTML_asCallBack=true, getHTML will be a normal callback - public void setHTML_asCallBack(Boolean value) { - HTML_asCallBack = value; - exec("javascript:RE.setHTML_asCallBack(" + value + ");"); - } - /// Whether or not the selection has a type specifically of "Range". public boolean hasRangeSelection() { return requestJSData("RE.rangeSelectionExists()"); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index f2cca68..eb75d02 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -1,8 +1,10 @@ package jp.wasabeef.sample; +import android.content.Intent; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.TextView; @@ -32,11 +34,13 @@ protected void onCreate(Bundle savedInstanceState) { //mEditor.setInputEnabled(false); mEditor.LoadFont("Alita Brush","Alita Brush.ttf"); mPreview = (TextView) findViewById(R.id.preview); - //mEditor.setHTML_asCallBack(true); mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { - mPreview.setText(text); + mEditor.setOnJSDataListener(value -> { + mPreview.setText(value); + }); + mEditor.getHtml(); } }); From d05e9dc83cae89665983859592a4959ff56fae14 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 4 Feb 2023 13:10:43 +0100 Subject: [PATCH 054/136] gradle:7.4.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4763e28..b209aa0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.0' + classpath 'com.android.tools.build:gradle:7.4.1' // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' From 595c87d4c1a6c6ca5cbe4e13819e4ac377f8b877 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 8 Feb 2023 20:05:59 +0100 Subject: [PATCH 055/136] work on callbacks --- richeditor/src/main/assets/rich_editor.js | 39 +++++++------------ .../jp/wasabeef/richeditor/RichEditor.java | 6 +-- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 170c2e7..d9fb085 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -87,8 +87,7 @@ RE.runCallbackQueue = function() { } setTimeout(function() { - var callback_text = "re-callback://" + RE.getCommandQueue(); - window.location.href = callback_text; + window.location.href = "re-callback://" + RE.getCommandQueue(); }, 0); }; @@ -298,24 +297,9 @@ function createCheckbox(node) { RE.setCheckbox = function() { var el = document.createElement("input"); el.setAttribute("type", "checkbox"); - //el.setAttribute("name", id); RE.insertHTML(" " + el.outerHTML + " "); RE.setElementListener("checkbox"); - - - //el = document.querySelector("input[name='" + id + "']"); - - - -// var elements = document.querySelectorAll(":hover"); -// var el = document.createElement("input"); -// RE.insertHTML(' '); -// el.setAttribute("type", "checkbox"); -// el.addEventListener("change", function() {createCheckbox(this);}); -// elements[elements.length - 1].appendChild(el); -// el.focus(); //sets focus to element - //focus should be behind the box...but i don't get it - RE.callback("input"); + //RE.callback("input"); }; RE.setJustifyLeft = function() { @@ -354,7 +338,7 @@ RE.insertImage = function(url, alt="", width="", height="" ) { } img.onload = RE.updateHeight; RE.insertHTML(img.outerHTML); - RE.callback("input"); + //RE.callback("input"); }; RE.insertVideo = function(url, alt="", width="", height="") { @@ -373,7 +357,7 @@ RE.insertVideo = function(url, alt="", width="", height="") { video.onload = RE.updateHeight; RE.insertHTML(video.outerHTML); - RE.callback("input"); + //RE.callback("input"); } RE.insertAudio = function(url, alt) { @@ -412,8 +396,11 @@ if (element=="link" || element=="") { for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { var ret = []; - ret.push(element); - ret.push(this.getAttribute("href")); + ret.push("click"); + ret.push(["tagName",this.tagName]); + ret.push(["url",this.href]); + ret.push(["text",this.innerHTML]); + ret.push(["title",this.title]); RE.callback(ret) ; } ); @@ -450,7 +437,7 @@ RE.insertCollapsibleSection = function(section, content) { e.innerHTML = '
'; elements[elements.length - 1].appendChild(e); - RE.callback("input"); + //RE.callback("input"); RE.setElementListener("section"); } @@ -463,7 +450,7 @@ RE.insertLink = function(url, text, title) { RE.restorerange(); document.execCommand("insertHTML",false,""+text+""); RE.setElementListener("link"); - RE.callback("input"); + //RE.callback("input"); }; RE.insertLinkSelection = function(url, text, title) { @@ -481,7 +468,7 @@ RE.insertLinkSelection = function(url, text, title) { sel.removeAllRanges(); sel.addRange(range); } - RE.callback("input"); + //RE.callback("input"); }; RE.prepareInsert = function() { @@ -537,7 +524,7 @@ RE.insertTable = function(width, height) { } RE.insertHTML(table.outerHTML); - RE.callback("input"); + //RE.callback("input"); }; function getNearestTableAncestor(htmlElementNode) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 119aa81..927c392 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -155,10 +155,10 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { } } - private void callback(String text) { - mContents = text.replaceFirst(CALLBACK_SCHEME, ""); + private void callback(String value) { + if (mTextChangeListener != null) { - mTextChangeListener.onTextChange(mContents); + mTextChangeListener.onTextChange(value.replaceFirst(CALLBACK_SCHEME, "")); } } From 047c049fcd979ce9f8ccf036d629c92afbdfe3a1 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 10 Feb 2023 18:27:49 +0100 Subject: [PATCH 056/136] work on callbacks --- richeditor/src/main/assets/rich_editor.js | 13 ++++---- .../jp/wasabeef/richeditor/RichEditor.java | 31 ++++++++++++------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index d9fb085..1b23701 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -256,7 +256,7 @@ RE.getFontFamily = function getFontFamily() { arr.push('cursive'); arr.push('fantasy'); // converted to set then arr to filter repetitive values - return [...new Set(arr)]; + return String(arr); } @@ -396,12 +396,11 @@ if (element=="link" || element=="") { for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { var ret = []; - ret.push("click"); - ret.push(["tagName",this.tagName]); - ret.push(["url",this.href]); - ret.push(["text",this.innerHTML]); - ret.push(["title",this.title]); - RE.callback(ret) ; + ret.push({"tagName":this.tagName}); + ret.push({"url":this.href}); + ret.push({"text":this.innerHTML}); + ret.push({"title":this.title}); + window.location.href = "re-click://" + JSON.stringify(ret); } ); } diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 927c392..f094851 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -60,6 +60,11 @@ public interface onJSDataListener { //public void onActionFailure(Throwable throwableError); } + public interface onClickListener { + public void onClick(String value); + //public void onActionFailure(Throwable throwableError); + } + public interface OnTextChangeListener { void onTextChange(String text); } @@ -75,10 +80,11 @@ public interface AfterInitialLoadListener { private static final String SETUP_HTML = "file:///android_asset/rich_editor.html"; private static final String CALLBACK_SCHEME = "re-callback://"; private static final String STATE_SCHEME = "re-state://"; - private static boolean HTML_asCallBack = false; + private static final String CLICK_SCHEME= "re-click://"; private boolean isReady = false; private String mContents; private OnTextChangeListener mTextChangeListener; + private onClickListener mClickListener; private onJSDataListener mJSDataListener; private OnDecorationStateListener mDecorationStateListener; private AfterInitialLoadListener mLoadListener; @@ -113,6 +119,10 @@ public void setOnTextChangeListener(OnTextChangeListener listener) { mTextChangeListener = listener; } + public void setOnClickListener(onClickListener listener) { + mClickListener = listener; + } + public void setOnJSDataListener(onJSDataListener listener) { mJSDataListener = listener; } @@ -135,19 +145,9 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { } if (!"null".equals(unescaped)) { - if(unescaped.startsWith("[")) { - // Array - unescaped = unescaped.substring(2, unescaped.length() - 2) // remove wrapping quotes - .replace("\\\\", "\\") // unescape \\ -> \ - .replace("\\\"", "\"") // unescape \" -> " - .replace("\",\"", ";") ; // replace "," -> ; - - } else { unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes .replace("\\\\", "\\") // unescape \\ -> \ .replace("\\\"", "\""); // unescape \" -> " - - } } if (mJSDataListener != null) { @@ -162,6 +162,12 @@ private void callback(String value) { } } + private void callback_click(String value) { + if (mClickListener != null) { + mClickListener.onClick(value.replaceFirst(CLICK_SCHEME, "")); + } + } + private void stateCheck(String text) { String state = text.replaceFirst(STATE_SCHEME, "").toUpperCase(Locale.ENGLISH); List types = new ArrayList<>(); @@ -650,6 +656,9 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request } else if (TextUtils.indexOf(url, STATE_SCHEME) == 0) { stateCheck(decode); return true; + } else if (TextUtils.indexOf(url, CLICK_SCHEME) == 0) { + callback_click(decode); + return true; } return super.shouldOverrideUrlLoading(view, request); } From d3ed5172e31813110413334afd8e047d05540606 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 11 Feb 2023 10:34:30 +0100 Subject: [PATCH 057/136] clean up and fix checkboxes and links --- richeditor/src/main/assets/rich_editor.js | 4 ++-- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 1b23701..1ea8cea 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -110,7 +110,7 @@ RE.setHtml = function(contents) { images[i].onload = RE.updateHeight; } - //RE.editor.innerHTML = tempWrapper.innerHTML; + RE.setElementListener(""); RE.updatePlaceholder(); RE.callback("input"); }; @@ -397,7 +397,7 @@ if (element=="link" || element=="") { coll[i].addEventListener("click", function() { var ret = []; ret.push({"tagName":this.tagName}); - ret.push({"url":this.href}); + ret.push({"href":this.href}); ret.push({"text":this.innerHTML}); ret.push({"title":this.title}); window.location.href = "re-click://" + JSON.stringify(ret); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index f094851..e2e516f 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -82,7 +82,6 @@ public interface AfterInitialLoadListener { private static final String STATE_SCHEME = "re-state://"; private static final String CLICK_SCHEME= "re-click://"; private boolean isReady = false; - private String mContents; private OnTextChangeListener mTextChangeListener; private onClickListener mClickListener; private onJSDataListener mJSDataListener; @@ -223,11 +222,9 @@ public void setHtml(String contents) { } try { exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');"); - exec("javascript:RE.setElementListener();"); } catch (UnsupportedEncodingException e) { // No handling } - mContents = contents; } public String getHtml() { From 9094ad030b846b0abc99077f77a97921bdcc9b9d Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 13 Feb 2023 13:43:04 +0100 Subject: [PATCH 058/136] fix setFontsize(), Bullet- and Numbered lists --- richeditor/src/main/assets/rich_editor.js | 8 +++++--- .../jp/wasabeef/richeditor/RichEditor.java | 10 ++++----- .../java/jp/wasabeef/sample/MainActivity.java | 19 +++++++++++++++--- .../src/main/res/drawable-xxhdpi/fontsize.png | Bin 0 -> 1773 bytes sample/src/main/res/layout/activity_main.xml | 8 ++++++++ 5 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/fontsize.png diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 1ea8cea..d6e38ae 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -150,8 +150,9 @@ RE.updatePlaceholder = function() { } }; -RE.setFontSize = function(size) { - RE.editor.style.fontSize = size; +RE.setFontSize = function(fontSize) { + document.execCommand("fontSize", false, fontSize); + //RE.editor.style.fontSize = size; }; RE.setBackgroundColor = function(color) { @@ -274,14 +275,15 @@ RE.setOutdent = function() { }; RE.setOrderedList = function() { + // setNumbers document.execCommand('insertOrderedList', false, null); }; RE.setUnorderedList = function() { + // setBullets document.execCommand('insertUnorderedList', false, null); }; - function createCheckbox(node) { var d = document.createElement("input"); d.setAttribute("type", "checkbox"); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index e2e516f..57a937d 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -442,13 +442,11 @@ public void setBlockquote() { exec("javascript:RE.setBlockquote();"); } - public void setBullets() { - exec("javascript:RE.setBullets();"); - } + public void setBullets() { setUnorderedList(); } + public void setUnorderedList() { exec("javascript:RE.setUnorderedList();"); } - public void setNumbers() { - exec("javascript:RE.setNumbers();"); - } + public void setNumbers() { setOrderedList(); } + public void setOrderedList() { exec("javascript:RE.setOrderedList();"); } public void insertHTML(String text) { exec("javascript:RE.prepareInsert();"); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index eb75d02..17e668d 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -16,7 +16,7 @@ public class MainActivity extends AppCompatActivity { private RichEditor mEditor; private TextView mPreview; - + private int fontsize=4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -34,6 +34,7 @@ protected void onCreate(Bundle savedInstanceState) { //mEditor.setInputEnabled(false); mEditor.LoadFont("Alita Brush","Alita Brush.ttf"); mPreview = (TextView) findViewById(R.id.preview); + mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override public void onTextChange(String text) { @@ -107,6 +108,18 @@ public void onClick(View v) { } }); + findViewById(R.id.action_fontsize).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fontsize==4) fontsize=7; + else + fontsize=4; + mEditor.setFontSize(fontsize); + } + }); + + + findViewById(R.id.action_font_cursive).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -234,14 +247,14 @@ public void onClick(View v) { findViewById(R.id.action_insert_bullets).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setBullets(); + mEditor.setUnorderedList(); } }); findViewById(R.id.action_insert_numbers).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setNumbers(); + mEditor.setOrderedList(); } }); diff --git a/sample/src/main/res/drawable-xxhdpi/fontsize.png b/sample/src/main/res/drawable-xxhdpi/fontsize.png new file mode 100644 index 0000000000000000000000000000000000000000..a3befce101d8148784a3624807ca46c110c1e6f8 GIT binary patch literal 1773 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$farfo+SYi(^Pd+}qh_^Fu-<+WpgS z1x*Q)KDuJ-!rmsaBT2k7vX&lk{mE}~F`*;z;VB2FDYD#2F%n|G`X>nZh)>usy;XZr zf=}-;wHyw4vB&Ov_vxqmrMWR%%cM-l1`(Dd^Sl>7M zk$nVrY4-;28!wrkuhdyoplS1DSNkRJwEB+``qk!9h4U`G?`*S*cR%tz_FF*Eh>s)lazRt!#F9!_DL8@>hyCU*eD#Shwp-;s(pMvwGI`jv8;{JhDTN zA2of>ztBAMFZ+=yX|vz1ci!#VE#|l5*BcS@Irc60UVfJsc%6IW%{+_uyZ(O(w5Zw{ z{C&r})Cmo<(r@^f*WCT->%Eho%YV!D()Z6eS5$su+w$VivZX9b{5QGYdCsxo`wjELU=VGhg!MTyg*A&6`hte0+TJV?9bdHy1+T`Jo$*HlNWy-XMA}@-WR+g4C zb#!%A+4<#kt{iUXS1*5m?<`N+*HcrqXCBu%^!N97_2lH_U$+DT=3a@vw5#-Wm>SRO z>3XrJY|;)21r=wL}{Z%`7NK&l|n+$Sd{{&u$MNIyT%H}Bq_nUx3E#_g}OwJd(-^Q>^~tM@El z|JxXHo&Y+Pt+1-fDl$6y^qvP{;o;$j>!0d|;PV|;FAoO6rEDgqrc-0~R+;WBetwR* z^4*=CK}=He^8VMZUpGFV|MgHSH!zZKv@0*Tc=2LNVxnSXOiYc!^JmW{g{_`idFTJ_ zvfXoKED97p{|N&oi@B9&nrbbW4jocaknvzT)QFW@W3zzu`TRZK4Q|L(GgqCSDsf@M zXMZ#Oyd99d_pUSFV*koG8Ls7T|4g>k{`cmOqM3F4MqsYIc2s=M{SbY=*2_ZMyZk$* z&$T~tfA0DlGKbUdclcZFUzrze@k^!OO8&xfy;_N!zQoPv=iV=xt*yC0v9Q}h^PNb2 z(LaTUZBnn_|6SYG)>b!leK9cO=O^yUefVPXi?h?>zAZc2A9MfUhHGsVUw#Xp%U==w zYS~iOCFappC#(JLT+P~QSA3WG)zZMLvrYD1KK|;e?jgPJk0+kpH{pG`rTm1vm9wV_ zO<44PYSqch-_JciYFo5Gc&>L6uq;weU0izemGIBH{?E5xw(UyQ{BGa)!ED)6JKcRM z?_}lV;-(y~)olM0_OHhI&)uJ|zHaJ#x_bTIyaH$QiMjhG^?os)zxQ1JGN9I_duzWg zI{NDDm&cE$d^S(k@9*h(BP{-8LH_pJZ_AH--w<^Fs&2~U>m|~6S8Se|2i6f+%M_LK zBOs7}k-W|;_MoZ*;aB{8A~q)WpEKJvF>mSYmu0&WUxv?j$afKbRQ5c7P5M#s*ypQS zrmm8HaduPQqT4Urc7;Cu$l~Pki@&hnqTXV!VfCq>-*2Q_Wqpm9_ptOjZwdF^Cx*|> zFRjfI^mpJFa=IjKR2zS_|Jc_JzgBMD#p`Xl=iRQxyoIx0m?_S=b>y+oO23=_+qpUwZ5U33 + + Date: Wed, 15 Feb 2023 20:39:17 +0100 Subject: [PATCH 059/136] fixes for sections --- richeditor/src/main/assets/rich_editor.js | 2 +- richeditor/src/main/assets/style.css | 9 +++++---- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index d6e38ae..447dddb 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2022 peter@niendo.de + * Copyright (C) 2022-2023 peter@niendo.de * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index 2064e03..bdef3e1 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 peter@niendo.de + * Copyright (C) 2022-2023 peter@niendo.de * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -93,12 +93,12 @@ td{padding:5px 10px; height:35px;} background-color: #777; color: white; cursor: pointer; - padding: 18px; + padding: 10px; width: 100%; border: none; text-align: left; outline: none; - font-size: 22px; + font-size: 17px; } .active, .collapsible:hover { @@ -118,9 +118,10 @@ td{padding:5px 10px; height:35px;} } .content { - padding: 0 18px; + padding: 0 15px; max-height: 0; overflow: hidden; transition: max-height 0.2s ease-out; background-color: #f1f1f1; + font-size: 12pt; } diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 57a937d..87ba164 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** - * Copyright (C) 2020 niendo + * Copyright (C) 2022-2023 niendo * Copyright (C) 2020 Wasabeef *

* Licensed under the Apache License, Version 2.0 (the "License"); From ce44094aa6daf554390bf7dbf8275a99ceaa6d96 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 22 Feb 2023 18:19:27 +0100 Subject: [PATCH 060/136] add callback "loaded" --- richeditor/src/main/assets/rich_editor.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 447dddb..cb3af54 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -109,10 +109,9 @@ RE.setHtml = function(contents) { for (var i = 0; i < images.length; i++) { images[i].onload = RE.updateHeight; } - RE.setElementListener(""); RE.updatePlaceholder(); - RE.callback("input"); + RE.callback("loaded"); }; RE.getHtml = function() { From 66235f5e009c2bd32e6c70c643ab23a0ccd4613f Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 19 Mar 2023 18:11:21 +0100 Subject: [PATCH 061/136] test --- richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 87ba164..e27170c 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -212,7 +212,6 @@ private void applyAttributes(Context context, AttributeSet attrs) { exec("javascript:RE.setTextAlign(\"center\")"); break; } - ta.recycle(); } From 7ad700ed4ff5e2f23118e2287ffe9e3ee639e29d Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 19 Mar 2023 18:13:04 +0100 Subject: [PATCH 062/136] get HTML from selected range --- richeditor/src/main/assets/rich_editor.js | 21 +++++++++++++++++++ .../jp/wasabeef/richeditor/RichEditor.java | 13 +++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index cb3af54..301e406 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -49,6 +49,27 @@ RE.rangeOrCaretSelectionExists = function() { return false; }; + +RE.selectedHtml = function() { + // https://stackoverflow.com/questions/5643635/how-to-get-selected-html-text-with-javascript + var html = ""; + if (typeof window.getSelection != "undefined") { + var sel = window.getSelection(); + if (sel.rangeCount) { + var container = document.createElement("div"); + for (var i = 0, len = sel.rangeCount; i < len; ++i) { + container.appendChild(sel.getRangeAt(i).cloneContents()); + } + html = container.innerHTML; + } + } else if (typeof document.selection != "undefined") { + if (document.selection.type == "Text") { + html = document.selection.createRange().htmlText; + } + } + return html; +} + // Returns selected text range RE.selectedText = function() { if (RE.rangeSelectionExists() == true) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index e27170c..f0af6b1 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -144,9 +144,10 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { } if (!"null".equals(unescaped)) { - unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes - .replace("\\\\", "\\") // unescape \\ -> \ - .replace("\\\"", "\""); // unescape \" -> " + unescaped = unescaped.substring(1, unescaped.length() - 1) // remove wrapping quotes + .replace("\\\\", "\\") // unescape \\ -> \ + .replace("\\\"", "\"") // unescape \" -> " + .replace("\\u003C", "<"); // unescape \u003c" -> < } if (mJSDataListener != null) { @@ -212,6 +213,7 @@ private void applyAttributes(Context context, AttributeSet attrs) { exec("javascript:RE.setTextAlign(\"center\")"); break; } + ta.recycle(); } @@ -241,6 +243,11 @@ public boolean getSelectedText() { return requestJSData("RE.selectedText()"); } + /// Returns HTML-Code from selected range + public boolean getSelectedHtml() { + return requestJSData("RE.selectedHtml()"); + } + /// The href of the current selection, if the current selection's parent is an anchor tag. /// Will be nil if there is no href, or it is an empty string. public boolean getSelectedHref() { From c91876cf7ed021dd506686addab27fbe75563bf7 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 19 Mar 2023 18:31:00 +0100 Subject: [PATCH 063/136] update gradle 7.4.2 signed-off-by: niendo1 Signed-off-by: niendo1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b209aa0..b32ad36 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.1' + classpath 'com.android.tools.build:gradle:7.4.2' // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' From 9ae3bcee5612d100cce1dd287ef7049790dd289e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 26 Mar 2023 18:57:49 +0200 Subject: [PATCH 064/136] upgrade gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b32ad36..1814e56 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:7.4.2' // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' From 93d446ba662fc70ac7426205e87ac0e087e5d173 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 26 Mar 2023 19:02:26 +0200 Subject: [PATCH 065/136] add toggle from kishannareshpal for bold, italic, underline and trikeThrough --- richeditor/src/main/assets/rich_editor.js | 106 ++++++++++++++++-- .../jp/wasabeef/richeditor/RichEditor.java | 32 ++++-- .../java/jp/wasabeef/sample/MainActivity.java | 8 +- 3 files changed, 124 insertions(+), 22 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 301e406..b0f65b9 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,6 @@ /** * Copyright (C) 2022-2023 peter@niendo.de + * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2015 Wasabeef * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -203,29 +204,114 @@ RE.redo = function() { document.execCommand('redo', false, null); }; -RE.setBold = function() { +RE.setBold = function(shouldEnable) { + let isBold = document.queryCommandState('bold'); + + if (!isBold && shouldEnable) + { + // Enable bold formatting + // ----------------------------- + // If bold formatting is not enabled + // then toggle it to enable. + RE.toggleBold(); + + } else if (isBold && !shouldEnable) + { + // Disable bold formatting + // ----------------------------- + // If bold formatting is enabled + // then toggle it to disable. + RE.toggleBold(); + } +} + +RE.toggleBold = function() { document.execCommand('bold', false, null); -}; +} -RE.setItalic = function() { +RE.setItalic = function(shouldEnable) { + let isItalic = document.queryCommandState('italic'); + + if (!isItalic && shouldEnable) + { + // Enable italic formatting + // ----------------------------- + // If italic formatting is not enabled + // then toggle it to enable. + RE.toggleItalic(); + + } else if (isItalic && !shouldEnable) + { + // Disable italic formatting + // ----------------------------- + // If italic formatting is enabled + // then toggle it to disable. + RE.toggleItalic(); + } +} + +RE.toggleItalic = function() { document.execCommand('italic', false, null); -}; +} RE.setSubscript = function() { document.execCommand('subscript', false, null); -}; +} RE.setSuperscript = function() { document.execCommand('superscript', false, null); -}; +} + +RE.setStrikeThrough = function(shouldEnable) { + let isStrikeThrough = document.queryCommandState('strikeThrough'); + + if (!isStrikeThrough && shouldEnable) + { + // Enable strikethrough formatting + // ----------------------------- + // If strikethrough formatting is not enabled + // then toggle it to enable. + RE.toggleStrikeThrough(); + + } else if (isStrikeThrough && !shouldEnable) + { + + // Disable strikethrough formatting + // ----------------------------- + // If strikethrough formatting is enabled + // then toggle it to disable. + RE.toggleStrikeThrough(); + } +} -RE.setStrikeThrough = function() { +RE.toggleStrikeThrough = function() { document.execCommand('strikeThrough', false, null); -}; +} -RE.setUnderline = function() { +RE.setUnderline = function(shouldEnable) { + let isUnderline = document.queryCommandState('underline'); + + if (!isUnderline && shouldEnable) + { + // Enable underline formatting + // ----------------------------- + // If underline formatting is not enabled + // then toggle it to enable. + RE.toggleUnderline(); + + } else if (isUnderline && !shouldEnable) + { + // Disable underline formatting + // ----------------------------- + // If underline formatting is enabled + // then toggle it to disable. + RE.toggleUnderline(); + } +} + +RE.toggleUnderline = function() { document.execCommand('underline', false, null); -}; +} RE.setTextColor = function(color) { RE.restorerange(); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index f0af6b1..8de8566 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -32,6 +32,7 @@ /** * Copyright (C) 2022-2023 niendo + * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2020 Wasabeef *

* Licensed under the Apache License, Version 2.0 (the "License"); @@ -353,13 +354,20 @@ public void undo() { public void redo() { exec("javascript:RE.redo();"); } + public void toggleBold() { + exec("javascript:RE.toggleBold();"); + } + + public void setBold(boolean enabled) { + exec("javascript:RE.setBold(" + enabled + ");"); + } - public void setBold() { - exec("javascript:RE.setBold();"); + public void toggleItalic() { + exec("javascript:RE.toggleItalic();"); } - public void setItalic() { - exec("javascript:RE.setItalic();"); + public void setItalic(boolean enabled) { + exec("javascript:RE.setItalic(" + enabled + ");"); } public void setSubscript() { @@ -370,12 +378,20 @@ public void setSuperscript() { exec("javascript:RE.setSuperscript();"); } - public void setStrikeThrough() { - exec("javascript:RE.setStrikeThrough();"); + public void toggleStrikeThrough() { + exec("javascript:RE.toggleStrikeThrough();"); + } + + public void setStrikeThrough(boolean enabled) { + exec("javascript:RE.setStrikeThrough(" + enabled + ");"); + } + + public void toggleUnderline() { + exec("javascript:RE.toggleUnderline();"); } - public void setUnderline() { - exec("javascript:RE.setUnderline();"); + public void setUnderline(boolean enabled) { + exec("javascript:RE.setUnderline(" + enabled + ");"); } public void setTextColor(int color) { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 17e668d..0b104f1 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -69,14 +69,14 @@ public void onClick(View v) { findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setBold(); + mEditor.toggleBold(); } }); findViewById(R.id.action_italic).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setItalic(); + mEditor.toggleItalic(); } }); @@ -97,14 +97,14 @@ public void onClick(View v) { findViewById(R.id.action_strikethrough).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setStrikeThrough(); + mEditor.toggleStrikeThrough(); } }); findViewById(R.id.action_underline).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.setUnderline(); + mEditor.toggleUnderline(); } }); From 00704e97805bcaccc818455d3ed199e1379ab7e2 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 28 Mar 2023 19:01:12 +0200 Subject: [PATCH 066/136] add section PRE --- README.md | 1 + richeditor/src/main/assets/rich_editor.js | 7 +++---- .../java/jp/wasabeef/richeditor/RichEditor.java | 5 +++++ .../java/jp/wasabeef/sample/MainActivity.java | 7 +++++++ sample/src/main/res/drawable-xxhdpi/pre.png | Bin 0 -> 605 bytes sample/src/main/res/layout/activity_main.xml | 8 ++++++++ 6 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 sample/src/main/res/drawable-xxhdpi/pre.png diff --git a/README.md b/README.md index 4433ff8..339e5c4 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Supported Functions - [x] Justify Center - [x] Justify Right - [x] Blockquote +- [x] (new) Pre-Section - [x] Heading 1 - [x] Heading 2 - [x] Heading 3 diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index b0f65b9..e0821b4 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -366,6 +366,9 @@ RE.getFontFamily = function getFontFamily() { return String(arr); } +RE.setPre = function() { + document.execCommand('formatBlock', false, '

');
+}
 
 RE.setHeading = function(heading) {
     var sel = document.getSelection().getRangeAt(0).startContainer.parentNode;
@@ -536,14 +539,10 @@ RE.insertCollapsibleSection = function(section, content) {
     e.setAttribute("class", "content");
     e.innerHTML = '

' + content + '

'; elements[elements.length - 1].appendChild(e); - - - // next empty element e=document.createElement("p"); e.innerHTML = '
'; elements[elements.length - 1].appendChild(e); - //RE.callback("input"); RE.setElementListener("section"); } diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 8de8566..2eeb5ef 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -354,6 +354,11 @@ public void undo() { public void redo() { exec("javascript:RE.redo();"); } + + public void setPre() { + exec("javascript:RE.setPre();"); + } + public void toggleBold() { exec("javascript:RE.toggleBold();"); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 0b104f1..2cec91b 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -66,6 +66,13 @@ public void onClick(View v) { } }); + findViewById(R.id.action_pre).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mEditor.setPre(); + } + }); + findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/sample/src/main/res/drawable-xxhdpi/pre.png b/sample/src/main/res/drawable-xxhdpi/pre.png new file mode 100644 index 0000000000000000000000000000000000000000..0c39b0c1a1dfa3007a1b0da668f6bf60ea3e8185 GIT binary patch literal 605 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U{djPaSW-5dwcs}ZnPthYvA+; zeMWO#WK~p`G%sP^*}Q{!bMp@6G`XIfcTJzfEq)ztV4tD-(}PJ&;XqYY*4nMtqO#X+ zt=;ka`p>%a-@hFwpPOGWZS5Jx`Okkpe*Wv^&TS8$%Ris5oo;U+u5066AIUxWS!g6)Kk4Quy`4( z(f+JERi}RGJdVq}GAFa~;IGgrM?W-dwCkN^tZNXlziX3(oWZr_AeC&d!vn<*Gavf} z(taS}uhyxgiUSezfo6)G__M0;wdU*15Hm$n?q~zGuT_AU$twBXYwux%1QZ6#N6n?X@WDi}9Bmn?Bu`d;AbE*)Vvz`njxg HN@xNA6LvKW literal 0 HcmV?d00001 diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index eab30ec..beb5402 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -230,6 +230,14 @@ android:contentDescription="@null" android:src="@drawable/blockquote" /> + + Date: Tue, 28 Mar 2023 19:02:27 +0200 Subject: [PATCH 067/136] * just add a line break * add

after inserting some elements --- richeditor/src/main/assets/rich_editor.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index e0821b4..17b6c68 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -368,6 +368,15 @@ RE.getFontFamily = function getFontFamily() { RE.setPre = function() { document.execCommand('formatBlock', false, '

');
+      RE.setNewParagraph();
+
+}
+
+RE.setNewParagraph = function() {
+        var elements = document.querySelectorAll(":hover");
+        var e=document.createElement("p");
+        e.innerHTML = '
'; + elements[elements.length - 1].appendChild(e); } RE.setHeading = function(heading) { @@ -435,6 +444,7 @@ RE.setLineHeight = function(height) { RE.setBlockquote = function() { document.execCommand('formatBlock', false, '
'); + RE.setNewParagraph(); }; RE.insertImage = function(url, alt="", width="", height="" ) { @@ -628,8 +638,8 @@ RE.insertTable = function(width, height) { var cell = row.insertCell(); } } - RE.insertHTML(table.outerHTML); + RE.setNewParagraph(); //RE.callback("input"); }; @@ -857,3 +867,11 @@ RE.editor.addEventListener("keyup", function(e) { }); RE.editor.addEventListener("click", RE.enabledEditingItems); */ + +//https://stackoverflow.com/questions/18552336/prevent-contenteditable-adding-div-on-enter-chrome +RE.editor.addEventListener("keydown", function(e) { + if(e.keyCode===13){ //enter && shift + document.execCommand('insertLineBreak') + e.preventDefault(); //Prevent default browser behavior + } +}); From c69bc571d9dad16619b7a05b6085cbdeca6da2ee Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 28 Mar 2023 19:50:58 +0200 Subject: [PATCH 068/136] fix lists signed-off-by: niendo1 Signed-off-by: niendo1 --- richeditor/src/main/assets/rich_editor.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 17b6c68..341d44f 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -870,8 +870,9 @@ RE.editor.addEventListener("click", RE.enabledEditingItems); //https://stackoverflow.com/questions/18552336/prevent-contenteditable-adding-div-on-enter-chrome RE.editor.addEventListener("keydown", function(e) { - if(e.keyCode===13){ //enter && shift - document.execCommand('insertLineBreak') +let isList=document.queryCommandState('insertOrderedList') || document.queryCommandState('insertUnorderedList'); + if(e.keyCode===13 && !isList){ //enter && shift + document.execCommand('insertLineBreak'); e.preventDefault(); //Prevent default browser behavior } }); From 498bdf004772513e4736c64cc44f764de362f15c Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 18 Apr 2023 13:05:30 +0200 Subject: [PATCH 069/136] cleanup jcenter appcompat 1.6.1 --- build.gradle | 5 ----- sample/build.gradle | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 1814e56..6136ab4 100644 --- a/build.gradle +++ b/build.gradle @@ -7,10 +7,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:7.4.2' - - // TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ -// classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5' -// classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } } @@ -18,6 +14,5 @@ allprojects { repositories { google() mavenCentral() - jcenter() } } diff --git a/sample/build.gradle b/sample/build.gradle index 23d5591..2f18d6c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -38,5 +38,5 @@ repositories { dependencies { implementation project(':richeditor') - implementation "androidx.appcompat:appcompat:1.5.1" + implementation "androidx.appcompat:appcompat:1.6.1" } From 110befbda8a9082e59e9d39abb0a737e56b8cfa6 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 23 Apr 2023 11:57:31 +0200 Subject: [PATCH 070/136] gradle 8.0.0 --- build.gradle | 2 +- gradle.properties | 3 +++ gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 6 ++---- gradlew | 12 ++++-------- gradlew.bat | 1 - richeditor/build.gradle | 3 ++- 7 files changed, 12 insertions(+), 15 deletions(-) diff --git a/build.gradle b/build.gradle index 6136ab4..c1546a6 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.0.0' } } diff --git a/gradle.properties b/gradle.properties index 5517438..37cbe9e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,7 @@ ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=33 TARGET_SDK_VERSION=33 MIN_SDK_VERSION=24 +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 35766 zcmZ6TQ*>rs)Mit$ZQHhO+qP}J;Tzko*tRRSU9oMal2ljs=<)aX`hJabHP3$5o@<>0 z+y`6!4c0*S13}rfE2|m?1cU(-1cWwa-VZZH@dqxz8+{Dp8!E4*e5J^>D2lW|f-j0x zo<(~QnFNO1pI8`Gd=Dh1B^mL?ab$;(Lh-=8JXtcDpd5?J1y(UPr2%wU(aZOC<-9lL zfcxF*)xE2UIN)87z5VfIhVHN5;|_d+;QhP>h}{S&#GHB~#GGp3!G^1MJbr%lo)4`o zc_%nvPRltX1nccyRLGDVhDq}twP!iOEwD#^U`j(>W|X!^l(A2Bq}thVpjupbJb$tJs_GSbRy=NhT>;2vm1Jp_7P7}k!J11JV$6$a@ojwipW`qx8>vXJJ zJ?zdA<96Wd;j-7&y8wUZb`0vX<7W{%()c?7O2Z!-sp^ecl~$6a?0}R|mAP(@jFxjh zIhxOTBZ1C!Nb1X5dw}fW(aiP!kXA5QDScnJ7E8 zW{-~6^Pn2k&Fjj}2Ckjx{MvEXtEAXY>rYahfIyx>Hw5VZ;Rj7GOVwBeZnpy+Dv>P! zGjqds6s?W0{q=I8gany>eP?xNX%WZKX==PuvH9xy+WvMz8S6wDjx)_Zewge9Gq_0k zEAWR=HIJ|Z#=i8{dR{C6TMglt_Hv?R_Lr}FzoWzvzrxeTP*T{hrUn}X4n&;~;bm)n zhjTJA;7Z3(7NN6M_mgz4;=Ac5MkX47SN*K1*q|LqUH{umM_55_r&15}m{Drjev2>) zSD%5XQJ(QP3Kf{R!Uun#|9FREeI%^-Jz|lJy~g+~DJU z@}jhnz%n*4U3{jH#O4aLo;oZ~;-*?!?e`q^m&_*lUsR@Vuugr{mlw7#;AMPBJq!28 zFJVD=aoQsXXU9xeE7pV7LVn#q{p!VZ3%Y7}jE47Oc_kZjN{$2I_Ih`Hid_gb!z77k zLEPp?R;<|(jHShvV>3q;6{-VZbkCCwhse5}9x5_xyKM(xnjv^V-XBsASA(EHumh^r zu4uRPY+C7=BU8QW{OGSZAfm^B!Ait0-jY>*sG>$R-+;7@n-8id2AU2mHkJf0=Ox7L z3wA>N`?)k>o~;OBOg*l9-c&2Ax>sd#(g1YY--PWe-tT@R^ihOGFOUaF!s{7t|8@Ch z_a_pXzZ3hE9!TK$1W#azp-gEOQ-WuU#0`utpn2;A8trA^l6q$YQF51^@s+gh=n(ox zoxo50I#y^dUD+qqZWwdRChW+6_RmN-hX4{Bk=n^oC1Z8WWcqd|_FqA#1Txzjttspk z$qnVX*9wL95^mN zFaghCQlK}=ONlTTi^uzFqhx1MtD@5q52vJ+NFxQ!u7FgleEERVM{9Q0KxyV+k(#!U zjP{AHSQz$~(Idp)Q>buZc_HZTh*;6r2LVj?1C+I;u46gWXMuJCdyY<=&+h zm4(^0&>UeXB@WOkTUHnuLdRJ}V^~#YwH&^#l%E<;i*sXUO>N1{m4ma@FJx=_#Nw;< z>DuvrnXPe9bTKX@WWBobWN|7oK=)Lm*uH{jQz)jjk}-j>shi7zn|@FwV-hX@U0v25h!EE-T`2>;fbnoybY~s9BLR+`KF%Q zDzbQ>Qv(mtg1L{<#PeylU~f84G=c~OVgw9kph^bB%mbG$j0Gi*<7%^`biLCi$6A3Ua2o<@&WZB%x_Qab`4f8RYu2zo&RGMRxDj1!RG($dfM3s(BZguTy zLQ~Oa_37Ex6x&lHa@^$nGLNS@^H2-MXqXBgn+7g$+NPHtFwcLI4Xtep*>ku19Ga^p zp#I$0_;mELs}quj#0<%t{k44%{7sS|V3?G1-3ZXqJ$R|-W>adjIc-=-Eg~5@2km53 z@Xnl(UkDbZjcc2EDxRKDmzlg3g;+`NXn<32Cs&Gr8M9>iNKNBkYED;3NV$c>%@2(7 zGuZSz;-4HW^C9IKoKie9{tDcJelMU3LgIin!vgno;{>zF^|F}Zn0+;$q2u1o;iwNQ z*ah^oyIql#CiRE(k02Ch-UkgWPBjjbKsFW>pRn$MumX$j zqFLTNU8r{i;*{D$hD+hOUa3_r7*l8 zv!m^zk9RI`jl^J^vt>t_yJad>q#1C=@BvNJ3MPiI931*tyGN(dfE8@a@$)+PFz%6ktHtd^7EFEspL&_D^Xzo&X6_DQ78wf zz1psXF}CZ($`6(2F%C09Pw5W0$pQWGyoi+#B$=AsBzZ;_@JF(*yWu_ba8?#NS)qv3 zq)8|X$tO8<*Cm-6pLzt=@HH~~Whyl@SnX7DTU)W*f~rdggk(W%Z<}b!YT6ltALyJV z&W{eSCYIj#IUky_2kCU`3+UF0CXWJ{R8hft0T~UY^%aGF@Oo1BC3Im`#{kkc7=7sS z8CyJwKM+!`5Ng(Bjw7C=YqBjR4pZ2q^G&dX1t1Bk9B9@gNUD)hE_4oC1LkMMj*Bml z!1|Cs$=oA49A5dB(J*y(pS)A`;qu&G&y}CmAx;G$aS6rh0|Wz#;j$XWiYE!A`t z-nl(heIYdB4%$A?#G8lH%12=MhxWT30nM>+I;h~}7?yr1=LE_C8i57|Wo6{sNQ^>; z76_DvAknlKbXXCYyWKW}OVJIAO$mR9f1kA z`gr)*`~ttfA25CqYm&2*ElP{2i^7qjnqohhLcekYd2ZllD!}7e;-T;lQF}5|iT6py z$l_@r6W(PRz>DAk+cMkZ60X498M-8S!#MJ%S_YjdN(}{_^tcey;R#>;6?L~{leV>u zPbWCJT!zM&*IJeiG+#{cHEvY+ z+Lzy+60#``hEJ4SM{BO+Om>~)RW=p6jE0QoZkC2X1^f$hGAhP8_=LV(#|^Z~1k`J`5Y4{&kph&!7&$xsda&#_|163LJY#sev-!dySjv~soVP|ZwnwS8hqE7eW=?jZIr zi|q0V2R4CbUK!WWlN?7FFNm=IV8vl((EGk<62$xUXcUio))$cnA|RzW;>9U(Bnp6*3SvPm@L)RUplH%j@jDW74248VZ*?j*TrNov+S$c>Dg~fOE1Sik8ABjAeJthLGdbJHnAQl>~+P~ z#8EO}Y7Or4mzgHx>OH=BF}4#ZoI}bJDIC?5J}a%Y(U;mvo%ZW1r2&8f2;ee-6!*6Q zFsae|^`2GCb)p)TzZ{-!^I1Vp@Gyr_M=`Yr)@w?iR~9Kw1~6sAY<}DOF4BFc>oH<+*sWy5S1`mn zF_U-HR381t#PQ`v5doZKTAbNU&Q!FVsUhGIj1!oSU@eSlp5BJPTk$s@L7bUstn`sLU5{#Kyg$T}jmaPaIaQUY)z>ik7Gtj+=Nj;AU=gg&6F~`6+*>>bh zaKRIBVV{_t+a0vt?L;AJae1#NN3)b4T4J^{&oTSdK$>TA&jL2srV0Bw&K~20G=K|j zcmh{_ur7h{M7$gy0P9R^qHnt{2bc55gi`-njR>CF3==d!!^0k-~D{^(9K>;EN-H(QO zcZVNtB+4?UGKW*dGw=#54>WJ8zmpFY%WPBA)rS~ zPf*sTprcOzJg7evUSu! zamXo{%o5}g-xEvC$qkF|h4Yc;6zl5`G@*CeNRuDYY_Il}tj5jasMb`Qx$ZH!@Y3k6 z+vHg^XC|{@Ma$u!yS5RwTtFrB_OZi>IH14e>hHj(Hr+h7{XhjbX zmagNjzDdLH2|so87G^T9=ht^OPok%n@-B7JZd+EBohHA~h|rvTnJWJ-cH5wU9a3e0 zvh1;5>}1vXA)efRhiI*5y=m#|(c|RZ5MCv^G^Vm~bPhcT-P#6llM1*B)Q=|}n#G%- z`-^P3y#>dghcZ-yeS&?^yJeObqdBxnZ6z*>=yfI!cY~2T5*cEWyWcUED2Q2p@DKoz z^OkzZ20>xZGW_|beg{&(M*r^H<#dy|iqOg^qS$Jzp;gQ?*iK&xyqwoSNqVV9;-wY>Bspr8Ti;34;h$o4MC1^b+y{g*55ZzjeWc6f)u8Ng9YEkK>jNC-{Gs}VJgcq(_Z-0ggT3-5t0G)sPE93~qXib;- z5LBi{NKsUJY%s)ymtC2A6uR|VkQQsmlZ8kUrOP}~K7(I=^oSkGxQw1GjA0^MV%;%L z0MBEeSY!ch`*juR$+7!jxlX!YaQFf2)qaVx6X=@~yOIY|;Q7Tu&urcxOemAGWQ(_% z&%;!GQtn8uG%}mcAx~*me%RC!O0xY2>NJ^*f>P#Kp-eBx45d;fTDndGZeXa&yJQ*0 za^P$+D(OSmdXmuwlJN$mZO$v0QWU^gG(CY-0dir%z;;(1zsS?Q1AKQj86wg$o7 ztaYCK?g)FeF_ehxGfp3bBUXIuApba`PhLixgH}sI7BA?5T!650fhsDPJussQVzT~L zP5z4y@!x}?g|=E(0Tcw}790dbGQ|XgAO(pKDn<8@0#K@EpoAuZF5va2QMp}pDk7RR zQo~vV)0?F%tU^IPdpV&b?6r{KV$U;U+A#_+^7mH^Q|6no{|gb${o(8lWT=GQf!OKn z7SHRJpQ4oz;O`yEFG^0h1{E6PX?mV5jwt~=Im%x9VoS4;QCgDzQhy8wG}fsV1JO1V zcM6lDQh@)v|NL%>uhf-KE=_w#{GDgG=1DGP^8y_P>Ioics)A5zUA;TspE3o<7$qF=&{j!*nQi@J1H*qy&fRj5}9W1>v(;&Vb7tAwk0(9 zX1sh-ItRzL-7*><-FadFS0C!q8K!i%5?|hQ67tW-8Q|}R+f@|t;Ic$CbWHI!seIY3 zIe^OgvEl}gt)2MvJ z;gtLYk>PVo4kG_^Iw>~XrqR+p-OR`089eK{vweJqASd7@vpFlX(jNH;^z~{Ws{A6+fmmO=-OL;THV; zus@QT@>O?g;0>5_oN7s6A7PvE~9pb-ae#N05e%sWJJtWYNI&ELSq4mldQ2=9# z`vU(jc>Y(av-6N3Ae1N|AOimb-s~ZM${Za5pr%El7L$$7&vy&yFYxq@%bWY6mo25l0o3OGDC2c!%j@--0`U3x+zz69A0F$wMN$02 zORhsol7=%CP5jV;jLF3iwdX9hOGcD6I_cCYPwEqhIezA^T%Q<77F`*0GiNr`~`L^B*Mo>e6ZO63)@J@Fqo>rU@%4g zBQ>m?f}iZCwpg7>R&Sj{rVPv+iupA-bbx1enWI+;``7|Oa603ZVjH;wL(-z&0Znn~ z5H9}mw0MTe1(!`*@n#Iwq7e=93k5VifES@sNo*bC9=`!3ii(saI8k~MU(3w{W)7{j zUX%$8JUix+_eX&S!K$iFTT_!=GiOa}i2>Qlq6IhOcG@ehjGEgLCyOEfv2W?$yv1pA zIb$!pW<8rs;3lQ>&p@Cd-A&~|d{)*yLI7wXBAv);-Uzk8`9NG(Ky@37L}C>qfUd6e zgMD-F76jWB3f@)Y8FvYnC7_nl=kLP-EIK8{+(i0@Bh^x9*Ey`dUcv1SFbl|8Wbv+X z+>Dkf5qZzB{ae|1+de+rvRmLoGeaFkTUW>|t2w31FZASyo~G8RV~8!DIzpA#uX0+B zXHtKPVE(#Qq>@_9kejW*=R5@qa7|1{-a~8>5rzd3_~-AbzRQ(`p<%kc!Q>RHp{|e4 z>=bO>kc~5O#H+3iU!9SYvvKvKb2bkFx_(qz&lP%RPW6rF=4zWu)Z>aAEaQj;Y>~C* zd`Ky5dZEUEtA5d*WDQDWo^GBzYRzxlwa^Miq`Dkc_xcY5)mpuSg>3PXOZ9jr@1l63yCA+^HtdWt8pJ@|jO!LFGFVy}u}e z`9~i8`sn_Hh=0)wWZv|J88rD}5%(K@m0GQ%LFkt2%%nt~pa*fxR4_oZ&z6)y*p{zV zRUn*J)hw+z%(U9$zKy`?{&d8xow>zdcD6xKtAXOU=+D5)B){w~17M;fWPpO18Wz$F zPpfrhxkK^mad29hK&^B(9#oyT-bQm*N)ngJ+l_Z0NGuDw{ zp-TM`@@k|JAodN{0HDOHmUqiSZjMZv*}sq(&f21cTnsw7^9vEr-tqJd5DV08SVD{1 zDi$GWtahLiXqnw(&tZ%5tDgmLru-2(yb4vjZ(qv5W3bNpeGw|#&y9OFCXZ9)J-kpE zU7p*%^z+d(+ha%34Ov~uopAsIdP(*$g;)#4oa*b1rnr}r77$-V?h9Y~C56Hp(qw%F zJ-9GRmRO`9g&Z|YW&CcEAca>8NAkmzX>yoQJ$j8rsV5k>5eX~uOPh3OcqOcP@HE!W znPD$aTWvp2dkyt=_;I>RMQkU?8!MSxIJ-YV*9F<(K+HWl zfgi3a;9LjJw*hu7#j*MvUvvTj?%W@Y7tDdn`!|@JbUr(@HCM^e?U%fAWYDIa&pXU9bBOn4OH)GDN@ z!C859;_}Q9pQ>Btil0}X`c44zc{qF2d0_zX_hEycusnBiKQCvX`r0HMy7gwSAF$ZS zf4Z#M1i(MwK8bchM%z_W2mBH^kcy2gXpsAiRk?@jO%5D#x#tT+1?*|L3_fb5`ZvWq zwB;P=M;{(_5>Bem&Y=Y(Z8m_}xu_*Vz#+%y9Z{{#P^mEPr}wM4p+l^Ba! z^ZK?EMLCCHGQ9UQ=|*cl&?WM3mGivfZtrv-tEkKkF~T?3@IW)kyU>5Lj(oVUsPtcx z_4F_A`2Q#Cc#iM@d1($xOUmeDf4%UwS21vCBNODsH^7<@l1M6GW+SkvvW=Msw6IpE zvu`k+_=@i1oSv56L{YwJaQt!9grhmvmP9@*uZn_1YHeMI>_XmPyjwHu}yYeQF zQ_0X$d+18Ra;isQFq1C8Dugvb=j^7A;-)T z8Kw>?m8MpJmwyhH10(K;hEnpTs$(9>q=neA*AeB=PclT})o$W0;XjvwlPGlY>qu$5 z%)3zAuD1jy#z8G)yz+!myes)LwIeKJcV+cauP-!z^ibZFRWn$Jj$HJypESxTxMs%E ze>(K3yoRkWh{Z1(r;RdLwaI*MJ@*htv`fr3Y+B?*Tk zPDkcp8W}1Y(Fcpzh&?}(5E+Ov{KJUC0zOyyw!#U|cpQBM6$~RJmDIz_zt>A?e1Af~ z|6Cl#{$l=BDx%hbDN2}Z!EU`yxISBGo=t!u;mK*g=+u*3cL+3ENWIM}%?^ecw&te5 zW_gC7GXcN&qcMoFNQF+E_xAt!FLiJ^!K!~m5C0?j|8;M>92CSQE(aatshs+g6eTnY z+j75!X?mS$FeESvi6JCto$$s|$T=AR!@b<75zp6Sfx(qnco*g)2L$0em0$*S%hbZ z`hR{Vo>@$__3*(XJr3L%zu&`(nXgo;G|8N=TXR&Gd5=~jJiw>ohjP*CYcIY4@=&rE z#Xct5tax4~5wZGoHx3C$T0J&7M{Gm8>ts5@f6=@3W}O+RDSWrtCR6kTzz-?+Jw^AQ zghRGphBr~sclWV>=aNiI7*K9ul%#XN0L_Sy$>YiW`mqe0N2Qjo%HtZJGoAims7@)$ zVV`7E#JR7X+f-JNM5O|kGMDB732L~GrrHBNKs{~ch6)pyDR{TwteT!X`9@2aHM;hy zz)X{d485vt%S>Lv)4<+}VBK;W9_yDArFAvn1fa4uq#NFBz%4(=Va{dR6{#y12G{=r zw|<4N=N`QNPIBsV%3PzXvTM0=e~VduZDwX>o`Fzcv^N#4``PH`*2NCcyi@AwT4&G9 zm|QqlDoM1640-GiR+*aX{SbyyNP-J8gwrG&2ECNMNaZ=;{(?ag;EJ`c^sO_m6WvU& z&KW{JWfJLc6TN_=I|p{1w+xMP3IYFTI>ua1UA^EfWIRHwk9uU_fq;KOET5Y30Cfb1 zk?ipC>Sui%?L`3!WtAX6cY{lOm!ucULQR)dG;3^!tTW=R%&CfK(}|8lW8zmCve^`iz7gS6@&q+I{Bt&^)2la;H9xqXTQ2Fm}r=k9Vqrd)7KLHr%9Fp6vDyI_5UvX;1dCZ4Zv>} z$ryCl=d0hZ1NyKUXwe#Ps)wBY*-M@Z=iYd)UZvQHuDZ1>wM;%h{+pgbM z)wWWm6In6A*7gjrvMBF64|94eJB^eNp6T@<>=JdtS@E8V!;aO+YJd^DfZO#Nj2wE6RN-CJ?_k8a;F8f z02oeQBD8u)&aFG<5~D*;8i7#oOmpg9UV#=Hc*jdM$QC3g*sfMlW@m?O*WxO5{6cd3 zX`ejZ3ysbJ4C^osr=4^_<}DyInJB!z@Tf3ms3<=>a}YcWQyM(IagxaqV5^+3PRm0S zETO@Ck9QOso5yG%6F3H6>UM8A{s|Z|+TQZKdP_YYw=42PI*Tz6EO+ZmT3cr0cyVA^y%#9?eYNQ2o-rbVekn1#E|tto40;x zKcvM&tt1g8<&8v4kVLh!d^QxbXF|0dDGpU)vO-C0#it~lciKZ0=teFhq38x5LHsW3 zmVFmKm-vu)H3_ccBrwtdF@;CkT(u*-lG9TC+)?U`%n}V%SHy4%WbPm557IYD&Mb8X(*P4x^A(SGZECio_ z*s4!Y947&NIu%xz8-5lJC+fEw@NF3@KZF}VwjNyT!HaQhw&u6R177I=cCNcov*|zL z4sKxdF&uJN0--#AC2sH_I?UBZ^j&k(?JP9jNu0gIORjh@^dCeLH$b;*K7N*MJdO03 zWg(1l!uXMI1#Dbp-GNQb85mVg|Kuo&%$_~6i#QO^jCanlgwna0MXz!njj2i_|HJs} z_=PkI8Q(iln)~HJ3Lw0pE`T1Vr8Mlqf1NhU=NF+#M(tAP-M(s9~Q+LW5xZ)iOJ z1(#je@5p6<(pG|a2{2uPbr}1k+3|h7!c&*6_haZcaoBWik=N?>@fi;aP7S7@xAUHE z*hn#x0M}eWpyz53`!jsehk_=6+;mtHtYVJ6*#Bs${WS;Y4k*=@q6a2jE}Ldvd@0RS zxX`!b5Q@(M9e0b9np0*xXq zOmUzs5|0}@2Q>f4|3$1sI>jOXD0tKvk4p3lRY@W&oln6`bg?^p6J>&7izET9lOlGX zab=n`!tbc^C|HpyPT>Uu^0LO)H)a$kVN8djN0gI8?-Sf1KJfI+?yp3OdW5L%Xo^b` zM-xA0ssWRA8Cb_r!LI=Mg}x9d6v2pyq`XmuCbQIADUu&UM+(y3T?u70KO-A&|4XT{ zLZAkCO1+p6VAp9;8U0(41|7~VXmgnd1BDA4Z>1L}mJ(G#e%vx-V`ztQzJc+0b<0!o zFO`x1!Z6fdkiXQ2oeVkK#3I=(r&9fodAGTn-`|gqSV3Sd4(2M&Nn#8MW1JV>rY2*e zp^1L`GEBZQfJHdqpb+Nd(mlJ4WVxXMC9@+r12TU!qw#5sgwj-wc}Q4jdCPPT{ETF?@Uj>Nt8%IAvk(o0faQv<++d z^?{2ephHKDBrzhm2lOkIhqLVJ^fhW2TD{@?xA_z1IGCgR-Mf!ATb5BBTW z<>EuEG9#_MtNM2?NFkdi`!x|invBmdf}BIi01*t0GdJHs_i+SZoI-BAG8E|ROq3vP z)j<=o%JEUO_Grn7S~%HV8Wa8z@6Wh1y7J9Q!l>En-QgU_Xmy8*^8Q#kxl~)->TA(v zef4ykvNXkEO(it9N^k|u9A#!R=ozZMO&PvT-a!#AIvk@yg9>dq<99g@HJO}R_J^FC zBn${l$A3ZpONaA}Hp2G5WVV9>0TKG2WM-Dsf=RQmWE$xFjS!((M_MX8>^?*%zX2k@Xy$a~*t`>n;%zt)IZVEq<~ z$RxOMPxD>j_Q8hmw|rme{S85It?&?zz~@bM$b^9G{?s3TV8Q=tjAaFXEeu^N=8ZyX z40~c_xY(@6`|CihpJU|>Ln1%kpy&^U(F}GKPNAjbhXuMv5@>(yYKiigyZ>OGMJ%P6 zN9rD0KLEWk!=(zRo}03Q@+Ww1$x(hyc9g7A%x$VaKU2#3UIk@}$Fg)IW%)%Wof>;q z)dV}iqeWM|E{}rB?0kv%n5nObtjBU?8ZOOJiT;=?#hpXeQ3kB91nr7!no-pXBb$a> z7i04gJV$ozM6Q2LI&Ob%<%B**Zh2eH^OS$-D*&{gUcDd7rb%0h4Ppuv|5*CM8+@|H z5~qGbwVz(ilVPn-I!lIP%bdt88T^TJug8iaNclGU|UAFJt|9q z96;UBx%57ZCC@F?B!Ie&(}=YOZsx+anhH%RudwPi=BCupCc^yN;saDfMU0y8boIs7 zpk`aQh{3}FhRt$rl*0xyw$*YLcH|(c?8af)PKtR^_J`a|oAvZ`_L{lbdYNPFr*2X%M5x^>k$K`6R_9iuS%>}$6YR!#e*x(9F^Y)fT zFJ8NQ5QCBlJJ?pKkf;nIXHUd&=BF(MGOOXAI9`0fqW_X z;!=^x<^JJaZOxT6?Q(J8R_XS*_D(i!;4!rv3WyX(?eL!^JdCE1GIXA;nG^FHq?vlj zk{WZ5s?kVJd_$`1_cg{ZiIR$V=z!DI12(eSSO-FRfl%V?SoULOtY-@HdHbTJ2|SON zSp-@bvu$}3baxB7TUSy?$P3Kk6b}utoD7@wj_IJYb6LpnoG}AYeTX|~Si6l`^agE? zPUQyM^{XM?;R!Gr(MV@dYC|j>=}a4nQ1H(1dPf-DnNK@BNBHh2obBYi34l?apkiBj zQ3xy+A}Y!pcrGQI2#}4{3KJemmHleLygC|QHAH2zN-TxjXuigz$H+A2C3G?ygw13v>_}Q)=jIGy(J;k;GZ)u$c9OXKm!Zk4L{=it zOtz-}!cADTgcd@Ua}TknHh?>i=Ah>2U!GV}D;)Qje1rwu#P2Z_|vpx0h50+0zWP@{TNcP;s0?A5KD4E$zWB(1)gq8MCVzJTr2npH)Wk9bQYzkJ0{|s zfSgN(g&S=+JF@WcLr9q_Raf|}Xg&C?AUuSv8p+*(Yw?O;hFO?VzK%Fb24G9H&7NO} zk}^N~6=L#03rmRt;CE-Jdj+sveP_3Vq$BS;uyy=h{ocMJ=^Ot%dEH;=h@gb8IW-IB*TzqHV`{AfTZAvjsWQMAAOx zrK8>Xt0X!Oi*?q+V4B^hE@UY}2NQvxD%I{*c_t6IMd3vi=ib29v~BMJnxMlYzrT@y zE!Ic%YM!YIz>0zJLuX|pr;SGF2?a2lx9c+nk@y`MiuEzQTDukma~(qgw+cq`LG8o{ zmG@7w2nz@&B6;zCAiNjq+mDAnAirig5-cQOOWYrrju?**(TNszhb!$iEKz`Z;n+LWu zM3sRu6IuFr$w7e;h6QO->}chMx_INTlVMSY5e5SOMoge~?tSG;Q&%lpRUfPI_0Zap zi`WZ*PJ%Ms-q8R3q;BeBFx79QY`MbqGQCMvEI*Oze3`^7isChyBns#+IESY?9A&sT z6y^2m)n>f92FQbl3RAk1EMViOCwMX^aul=@+Je9^I`v`2ZWlVuCYzn}(n4CvyE+on+*XzbWTn({Mq&|Lh!8xIr6BWqd4Y`+e(;ED! z8}OY%YYdEKpz)y7h4TdWYpcv~rcd%u#YpQ&4aHmW`#!ia=FXQ$k<}R8A9V=i7a-r@I|I}1Cc2k z$Hr64_0FCw9RBM@Yp*q6;_q^1fy4P z(bpznR@&%Kclg7aE87k#9EDJzM=(NYXL?PS6m%!s!P8 zt=)MxPIKMf7}{!W6SJd~s_shuy$C;q9?PW)AF(x#TrcHdIgSkro4 zahz;Q+4qLXxHZRNVdh4*uK=JD{PrYdb?~euzuzcniLv0(g_gGwGYE^SvMQq(|5*~a zM``!z@O|HDALpbIFaZACba;zWvX7U2?e%Vl;>vU2y79w%@?+mY5M-Ba+-LBhC$x5! zFcS>veT<7Aqj-Lc%i2_M#QP&@Z40Tl^UCJviNwemWb{X@_1W0?NfRtjkV@Qf z0QDZ+AlluNNsDoNPn~3VNdI7_u9L;D&6vjSB*~}X_~?M1gFOf zyGLns1g)gx_sIJxX9|0&nusXS)pfO3V_YTlcVb{ylxhIaP@laOTXBOyLN<&V z0}8fXRSSA4TB+swnqR~xi?rXWo)~KvS)?9PCHbg2E8Y(ISA5?Gg7jsK$#r$jeMn0Y zi*hLEt4TBVTVD2-7EFru>rN7p(dASs126pY#;EcVXcrBLbS{FM&(Nk|ZHJ&wKXJ57 z$(D@K%pBMVM==5Xad7u*>(NGsq&;$zuMG$V#Smi)v}DGU-YpX}))}Vm(lors^7a{& zVHRkf(o{u@;f$T2SW^m-6NbabD&K*Se8)Ub<5L~#JHuQ@V)`_IUmOoObtyuJzC1uY zH`mN`+83e`>x<(dBxj+`Zf2Z+YoYi8u_~*%k~8prXrVh``3XKSVW@?^J@^79zF=4l5r1YsRur~&`VroB>cy&XzE=IajU9avpDm28 zj?_Fcl8^d85er3&g)_fVA~K`RE_bu$?gYe=Bb7^&urdPA|y#{y*qP-Bnd!Gf@yZk>oc?|SUZ1E4fJcD>O|q7 za>m?fsDnGse3uJ6-GJS`hbSXZY5s#`Mw*4V53xznIp@qb*zj3J_g=+I`L|{AQdrWAXd}y3 zXs4q$<%((|qq6JC8WPVXH5ta?+pl4KsQVHAN)6gY$o+7}48I;a3O+6xm>PS9{0z4u z8s^ywr(LFNWFp&5?uF9bmsRuz_4(0@bP713{r52%w8v15Dkt5wKP@i(HDzT|ah~Rp z#xKnPWCRYw(Fju;{OQFsQ=QtL`3Mfo?$-ASjPO&R{ITCB`mOWi))ynZxa{?$HgoUn zrIFU1ea@i{sa&Bw8;8;@I0?Jc+&z0y>hOk>9VBK1CRdIG zzr2tP`Yw)=jVb&)7os6i>9}tF$P7SKXg2JsxuNruT+gWTYzo#rmv^2Ha$@;C-NUJA z`c@2=Hm^^`{iAn^&S`6t(}Cj-mO&i*a8)zq2N#G9Y5n#CFdwhw-*qGxZZ zNnM(8zlmYGE%88jxU7}B9R>4}Pb%bmOYjSKHY&Il~N#SFlVf}YJQ zEPU+9AOPD9{rANMT9aCS!066cpoLI24l5oWf6Sy&aJ}G;prH5R4ct54 zv;}C%13Kdhn%DLscVV*2`d8L}HwNH#CotTsmd~xeqwHd>;uu#x?lu{^uA_34rE%FR zynUIf6dY*pz}Pb`BjB_o0*+*i7sCp{#4z!^di6|YLhID}TojNXwggC0aI1~*8j1U= zu+dz3_z{LnOTRAH&r7LMCOm9*eq1SSI_Ia!k!t7D50ntNBN;s)+o2?CR{kp>@Csx1 zQ)vMxbl_TN5GTYkC1@275IK5J_VMHPfHhk%*`_tDi*I<4-lmOEZJ#7L)$B~Os(fJZ ziLf5qYiEontFR1G6a>Up8vXJ^m(XNqBQM8%yT5%yI<>5`tVdMrZ?Ma18!WMXUbM(oKC z;dZB286@@4LBTktO`7{TPx=n60%s?MqGVF3J!YkkRp5-(oFLp-Fef-GIMA1Kz-ZE+ z^2PWfK$zE)*Ad%4*4&@_g>ls{GC{UsH1VBtRsV2w*TUz5a9(c#AUM}VqcOZc{t{}Q z)l))30Q)YS{P-uKsQ!(IC{ylj@l$@CBLKqH_0*Px(ZAC%QDr+I)X|44h>=_GVQDL< z4_ZUmo>_k~$>~g*W-pu59pngseFrfKRv?X^Ros44k2M#HuFPge2y~ym1e`8@zrDZX z1+it${6rbTxf+Q4u{P`iM#ahuniH>J0GIE^&45qp9n{#r-B^*?(iTG^2_GN|*gYBPo&T~Vlmu#} z*|gG|0m(Xlf9)vPgRI#p;iaZG3%9(OdnP7<3dU73W$IDw?eD<2KgJ zgs$dS;DxRo#X3Co78@wp8O1S^s%D;SGmJHnA*{?c`?z&>9W-!U%;UfK;Q&jx83Jb3 zb3lHt80xjzvpFLl&juOp9VuGlG$B>*4XVP8auhtDuO8 zkdxIMcVp72m|D}oJ`=-EkpdQN+6j_vQy9uRIr%4Vuhim#wc9F~vFf6&qsKVtbT8G) zx$(=4bjY4EAeZb!t&n>8lVi<`|G-><8Q?Y)%$A97go3&2ZX%vZ5KUO(ivu{k5hYD8 zz1rs+;`5oLXEx5CwAg1$w>~km1qa@4`lu4rlUw7+t%=~_RqG0~uK-`%;1Ngr!x_&g z@D45*CkRQ4ie@*I(+Iil*Cz_*oXmT_874~CT5Aw@rquZ|{(`3OhTiU%FWrJ(XI|Icw^M z(FAMEe#t9+)LvXHG-_UOG=WC&Y0>+|{%_lO{hyx|`S-&Cq7>rGf7`|yyJ~nE=--Z< zIpG#)s?yZxy26{dpcEQ(ur_vj#JIS!6zJmBvlN{On~dEZ8^V8qf^W+ieP=04SVp{L zq8?=dOIhD!-@Xetc?&L*0q^L4>Q`fa2m6*Z6}RwJ85h* zww-*jZQE93+qTWdR&%;9&c)vUVLi`WbBr0WJ$0(TxqLxS^PB(X3S47h2m_CvjB zB7?Uy=zA>A7`#0RX!R2 z;o7Nr!cluI)=i!ozV4x|SQ56Da&V@1u$d0BagE$bBP#08#J&lWbU)&!rc7e3I~{2p zv>JsLOVU5L%K0_>gq*5Ae$T{uIB)?>`=$!3b6 zTBrT0a5kLQ{}wuon7oC4YIu}NA+T$WH1WB9m@J^_w9R9wH!9dFjqL{|-}QX`l~Cqh zn3l`wDa!&IM_uY*vogsvuKP^?d#mjpm=4Dc@jtCVC0q1*SB`!Yjhs9C?}@n`Bt1Fp zV*T}kFyfM_3%2|Uu2jB~*Q?mAgIp_l{N=_`YnkiB@F>4nE!Io3cK)#Tp1hpwR^E8& zT?YWh!J(*VRBJrQ#MaIz|88r^64~8Sf%j9(dW31rMA=;Cqxnz1x874+v$66THzFs? z!>mmj$Zc>4#u}6J=kL*yd?vE@kl`P%9rj6onBH0hFL0v6AGkHz0fhXAUYw?;=8zjO z^d-4w1n#wK>L)1HeTl&vRN_xr_q^N)2}U5M@`63zK0QO~5NWEMsa;7=N$n)3-j=$*Wn9dn+^T7noK(ucN@W9% z47Md5UMq809N9y}eC0a>Qbri^=ec`jhgpjp1}K*=;i2ZRh78$@XK2@j9-?26bFbfh z@asnq(O!^{o6ec_1i{t-BvJ{?!ebL+_4Fhe>?3E%7gxBrt9P`#0#IO-(?Y&j{5p?zJ- zoyysAuntO>Ym}of{o_W6edLMd73CSc8TRBgfo^1GKkPqlyF2|l6F6ky&M27V3#Ts@2vRIH*{iygOb~`f|oexMToOL4dkot;ZCLlfShXg?hY3*`P zTPqH5L{fWfRTDiz{0lCUolF#xtkXAcM2ktfHj6s;R%@uDQE#%2H2!*o^r=V~dxjJ1 z*vlm3mzr}qwm%(ZJYWoF$kB!uSiyQpxu?wIMjE1nUQT&lbxnl>89fa6JIuk?p70+P z2a>f0k(R0`6gy|9hk8(GZh+=nqjC41XK@MNgbS8@$^1~qzE!+aQSJtzD1j0Bk(-$| zIr8diKlRD6&y3?Zcm&d@o7{?N805=PMbXQz`|ck-X(-7=>iD_LI;WHRBk&Snp1-|3 z*rJ%TI6{JcYq$S+T?WWqsw-Zc81u)EL(2|Qe zE*ENq>O|eRvg$TDIrS~W6eq@WWJy@}de}C{sV=?BxxQjmts0_MjZPrh&%mFq+Db0j z*{`b?#d`s44Rzg7b12!*45f?JVHY3XgBpKIG8)Eh@9}$9YVy|DB1;jQpZ`>%?2%u` zo@dR7o}5LTW!8rFk;w@8hSLEJ#ygD5dMC(k4{A4urO9-M_Op%TXtJ zULnG0+8z1?5+54IVAqFLQOMJ0QAYYi`rYaUf=?M3=rOV;)aXQK=exsgN0BHYB&p}+ z{W(IbecGka*X=1FDGA{f(M{ERjkb^a=EqxXH_MVWM5r;8+Zxzouy3bwqYx(>0;(s* zxJ^-slyA3(pMbR%MJkp+QnW0|Cif+g#}`^&X!ib0=#DqIrx@rj#SBf|%`BpA@P5zH z8g0(csXG5dH4tJRx1cRVzR>=Rks$x(?T1hO*ZpJPMb zKvq;rmqeaa;-vxGL|5#bA5=U$i^A0>m`4xeb!P4Sbk>wj%`(~TYJTzextmh6Az11p z^E%V}*5^6L>#FS}=RViz>bL&aloKP$9L--P>Lp+fa6c6|>)}29Y%%vOpZ#(l6(e*% zb$Clo^_A#I(ZJque1c6pR9G~+y#=BW<@0c__ zx(vWc^}G8i0>8rE{m?V$93Ar1&pEpL+04$(fu&AiRyNp`3Z0YuC7o-M+uDG@mVm^Gfm67L>0tdcME^L5M z9;aNzjLZbb!1&JJd3U$HiOXnkax~9&ScvZWdV6uJvD#~8`Dt6Rt`yfg+v~x{^Os62 z0!PTCF&X>jq{=czY_Tk#sqIpsg*k@VUGtOO>g;w0E!yVx^q>%w5*yRh`sRj{s+|{A zQ)M++1AhOn*_!Ioj*hNsM4mtAaIV1b=ZELZb68hbNRi7lO~U^DBXrrn+fObRk<35Z z3UBue9b$sBZx8Jc?0+IkL=S&T@x}j0h|YFI$)Lee_5jU5^sQ?RWrBlNO2JOS3IWRNUR~Uz;ewb>#+%A(%H) z#f*>}gUf$=h7{&RH=%2%XW87=5vxQGMqNFe+LEr7UdQ0{&)o{~wW}(K53W*hPsKxj zcb%4P_K&!SJgE1n6E@F~N>M+__H-=p7-Cg!0~t6J^4_Sv-V}}@Pk`rFAW`sEbvXNh z(+Tkc7ZdOcU)DHwSx45lTiFwEy=H=(IzB_&OKONKN4y&1rk2|a>R+LS$8yQu@}F6M z=a@Nt*nwy;Ydk=!h3@6O`zq_z)RHP|gGR!OfG3?VIcCGYiLvY}3bEOW3$PX#f^V$v z;V_?w9>nDkEeJ^}JKd|BC6ua)Lmy+XE}E2_OyR4vrzcwXHJFtQlcED^Mz64=(#4re zBnG-HT5O@I4>W&2w5fYf>KjuTj^$+H?#7Pes4$85vIQ523WC{t$(+TdR!d#gX z>-!e<5Cs^`etP%!OIM=fG2glrVR4w*`Rp9I(FixK(tP5TNORc#=_E7$4h-Y=y*W+k zl9@j`^J9(L$xtRBXiR~?`VT4cVnpoEu~W2nmxA3AGe{9FXooD*^SyXgoG8In2vd zwy_A~#_d(@k~Q>d9JC<_3tCBkm?z^obvlV+87<(&>a`2mpnQR;xJgaDAsh<0%7*M@ z15=@nR?4*+%0lEmHjY@@9pMBA8-haZ0@!R1586ZB0%iGLlhM&+$)dosGFzNaE}1O- zP3_>3l$6LZnkot+XMi_+;RSYZ%-$eFSyv@MVzwElzOJ>%z1m-QoR+fGk=2dY1pRZ~ zohG-Hfs2#G78D2!gia-=W$cVA&o}p+SZY3VsW=2t^ANsucAQ1JjnRrbvPJ5|*%H%N ze1VJ>80N5iF!7Wu^g5H$R+9M{nuFud%5>W_%yByfyHjvW+^u>LdvAjS1R(xf(0}H# z{v{(^eo=nN8P3J%nz=D!d&Be5D~}~ z46>pkz{LOCYFPjB5(-TtFD{Z{yJlG|oT*Va6{vwiTo3rR;sK<~^omr5wp?OsMEhAS?(=bMc_|KrgcSOILA8 zal2i)CmrS5n){rG?08?f=u$>bE)8nzRS zR-At7_(`6UW1gH6x&I;!gFBtPfoR=zgHE7E-#}R2iNMPO<^9rraRAwDXbvg1Xq==uFW(SZ8Z|vW8mc9X6 zWX&%j|2~>q!a_GRuh~-5CidJIch{5EuLZaYx!fq2H4^_^XYBC*Vf|F^ zZ4%GMQ&K&a%6$3C_cd^A5G84?@6Gt(W`X?cPZ~B)8#o>Ovgd44&nTU%@a;sN*pdy) zo_wCs9orQ_1f_(FQv{$U_WdhA%(mpdEC$}F-JkccRQnX^tp!C1#wQD7*5)C6^X12I z?j$Y%d!TR|3i-8_@I^2`+mqTI_9T<{hlqpg zmcF+9sQnF9#W4Wy*P*vK^G@h;Amf}EYoyx3=joEhp9c^=sxLrGg`vf44HY(NG)J+| z|F?U2U_kV$f4xSVN0tuQufwaVu{g&Bm6DqFM3r%*Zb*E@1)0OknrZfV29iRO0Y;K6h1VcKwT!0*Za171EDtI+fsc@_|X>g|s zNk=>k9ZiZ0E6-{Lz%bU&j#34iXzzv_W z2D_9C?6=D=)@M#tf14cpSP_CZZ%J}Xf0&xQpY15NS`vU$89J3k;ZakLWw|a+-q1Sf zNppMF#yOe1wDEPAbLJ@w6t{^&-U#_r;o65=9~Hwp-A@0E@GGYUMy)A2`cmpuC`d$*xH`Q(~S z)I#_{A-VTwlQ$upw&Un*STJ3R3SNO8*A%K2k*2wUtpq|}{&)nn0b`9yM^+?Z1=mk+ zO0_MZYB0qslkYW?8q|d4XFKz1B7EPGyaoaeW=>7tV37Vg8P7eR5q*+wfymh&iaDd^ zN^smWa}TmP({jw(bfT=O865K){6a@r$6BUd<&vX>eueAMk(u!?Mavj8$KykMSd*Dq zfD8K~Hh(7ZG~pb<<_I*)x@IPgFAbF0CNnd; z(AwglQw8@c1&g4g+(vo)r^eALl*>f&SI|6l^EuEwmGfJSL19sOkmpcAzGQXi+8D|* z{O+Wc_>+=gvg!>I{!pu(M$`%0DGK?7GHTj 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 VwlMN}`%er%aGR6olj~j${vQ;P=LY}) delta 36524 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 Date: Wed, 26 Apr 2023 04:42:16 +0200 Subject: [PATCH 071/136] readme signed-off-by: niendo1 Signed-off-by: niendo1 --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 339e5c4..63107da 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,9 @@ editor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { ``` **Others** -Please refer the [samples](https://github.com/wasabeef/richeditor-android/blob/master/sample/src/main/java/jp/wasabeef/sample/MainActivity.java) for usage. +Please refer +the [samples](https://github.com/niendo1/richeditor-android/blob/master/sample/src/main/java/jp/wasabeef/sample/MainActivity.java) +for usage. Requirements -------------- @@ -192,11 +194,11 @@ Applications using RichEditor for Android Please [ping](mailto:dadadada.chop@gmail.com) me or send a pull request if you would like to be added here. -| Icon | Application | -|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| -| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) | -| < | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) | - +| Icon | Application | +|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) | +| | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) | +| | [ImapNotes3](https://f-droid.org/packages/de.niendo.ImapNotes3/) | Developed By ------- Daichi Furiya (Wasabeef) - From 6799f32ca113497a1b82743bf84c0dfff5c9027a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 26 Apr 2023 04:43:40 +0200 Subject: [PATCH 072/136] readme signed-off-by: niendo1 Signed-off-by: niendo1 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 63107da..406e00e 100644 --- a/README.md +++ b/README.md @@ -192,13 +192,14 @@ Android 4+ Applications using RichEditor for Android --- -Please [ping](mailto:dadadada.chop@gmail.com) me or send a pull request if you would like to be added here. +Please [ping](mailto:peter@niendo.de) me or send a pull request if you would like to be added here. | Icon | Application | |----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| | | [Ameba Ownd](https://play.google.com/store/apps/details?id=jp.co.cyberagent.madrid) | | | [ScorePal](https://play.google.com/store/apps/details?id=com.hfd.scorepal) | | | [ImapNotes3](https://f-droid.org/packages/de.niendo.ImapNotes3/) | + Developed By ------- Daichi Furiya (Wasabeef) - From 41f0e135f7ba9019d55ae89aa6b082eac588b86f Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 26 Apr 2023 04:48:53 +0200 Subject: [PATCH 073/136] readme signed-off-by: niendo1 Signed-off-by: niendo1 --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 406e00e..ff89417 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,9 @@ editor.setPlaceholder("Insert text here..."); ``` **Others** -Please refer the [samples](https://github.com/wasabeef/richeditor-android/blob/master/sample/src/main/java/jp/wasabeef/sample/MainActivity.java) for usage. +Please refer +the [samples](https://github.com/niendo1/richeditor-android/blob/master/sample/src/main/java/jp/wasabeef/sample/MainActivity.java) +for usage. ### Functions for ContentEditable --- @@ -187,7 +189,7 @@ for usage. Requirements -------------- -Android 4+ +Android 7+ (Level 24) Applications using RichEditor for Android --- @@ -208,6 +210,8 @@ Daichi Furiya (Wasabeef) - Follow me on Twitter +Peter Korf (niendo) - + Thanks ------- @@ -216,6 +220,7 @@ Thanks License ------- + Copyright (C) 2022-2023 niendo Copyright (C) 2020 Wasabeef Licensed under the Apache License, Version 2.0 (the "License"); From 6804fd1fe676027ec9a881b3bac45a369c4bd41e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 28 Apr 2023 19:31:37 +0200 Subject: [PATCH 074/136] add dialog for insert image signed-off-by: niendo1 Signed-off-by: niendo1 --- richeditor/src/main/assets/rich_editor.js | 14 +++++++++----- .../java/jp/wasabeef/richeditor/RichEditor.java | 11 ++++++----- .../main/java/jp/wasabeef/sample/MainActivity.java | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 341d44f..a320189 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -447,15 +447,19 @@ RE.setBlockquote = function() { RE.setNewParagraph(); }; -RE.insertImage = function(url, alt="", width="", height="" ) { +RE.insertImage = function(url, alt="", width="", height="", relative="false") { var img = document.createElement('img'); img.setAttribute("src", url); if (alt != "") img.setAttribute("alt", alt); - if (width == "auto") - img.setAttribute("id", "responsive-image"); - else if (width != "") { + if (relative == "true") { + if (width == "") width = "100"; + if (height == "") height = width; + img.setAttribute("style","width: "+width+"%; height: "+height+"%"); + } else { + if (width != "") img.setAttribute("width", width); - if (height != "") img.setAttribute("height", height); + if(height != "") + img.setAttribute("height", height); } img.onload = RE.updateHeight; RE.insertHTML(img.outerHTML); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 2eeb5ef..7f016fc 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -490,17 +490,18 @@ public void insertCollapsibleSection(String section, String content) { } /** - * {@link RichEditor#insertImage(String, String, String, String)} will show the original size of the image. + * {@link RichEditor#insertImage(String, String, String, String, Boolean)} will show the original size of the image. * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. * * @param url * @param alt - * @param width Width of the Image; auto=100% page width - * @param height + * @param width Width of the Image; if relative=true then 100 means 100% page width + * @param height Height of the Image + * @param relative Image size is relative to page width */ - public void insertImage(String url, String alt, String width, String height) { + public void insertImage(String url, String alt, String width, String height, Boolean relative) { exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "');"); + exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); } public void insertImageAsBase64(Uri imageURI, String alt,String width, String height) { diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 2cec91b..a74be9c 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -296,8 +296,8 @@ public void onClick(View v) { + '/' + getResources().getResourceTypeName(R.drawable.insert_image) + '/' + getResources().getResourceEntryName(R.drawable.bg_color); // image="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Hyoscyamus_niger_0003.JPG/449px-Hyoscyamus_niger_0003.JPG"; // image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; - mEditor.insertImageAsBase64(Uri.parse(image),"alt","auto",""); - //mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "auto",""); + //mEditor.insertImageAsBase64(Uri.parse(image),"alt","auto",""); + mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "","",true); } }); From 923b67edc3b8ab0e2d1a1c22e59b1757e50c179d Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 28 Apr 2023 19:33:59 +0200 Subject: [PATCH 075/136] html cleanups signed-off-by: niendo1 Signed-off-by: niendo1 --- richeditor/src/main/assets/rich_editor.js | 6 +++--- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index a320189..f63eaac 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -68,13 +68,13 @@ RE.selectedHtml = function() { html = document.selection.createRange().htmlText; } } - return html; + return encodeURIComponent(html); } // Returns selected text range RE.selectedText = function() { if (RE.rangeSelectionExists() == true) { - return document.getSelection().toString(); + return encodeURIComponent(document.getSelection().toString()); } return ""; }; @@ -125,7 +125,7 @@ RE.callback = function(method) { }; RE.setHtml = function(contents) { - RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));; + RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20')); var images = RE.editor.querySelectorAll("img"); for (var i = 0; i < images.length; i++) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 7f016fc..df6ef58 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -477,6 +477,9 @@ public void setBlockquote() { public void insertHTML(String text) { exec("javascript:RE.prepareInsert();"); + text = text.replace("\n", "
") + .replace("\\", "\\\\") + .replace("\"", "\\\""); // unescape \\ -> \ exec("javascript:RE.insertHTML('" + text + "');"); } From ef32e60a80bb0cb447aa79a33f86ec9def6394e5 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 28 Apr 2023 20:45:18 +0200 Subject: [PATCH 076/136] fix insertImageAsBase64 signed-off-by: niendo1 Signed-off-by: niendo1 --- .../jp/wasabeef/richeditor/RichEditor.java | 29 +++++++++---------- .../java/jp/wasabeef/richeditor/Utils.java | 12 ++++---- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index df6ef58..22768eb 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -507,27 +507,26 @@ public void insertImage(String url, String alt, String width, String height, Boo exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); } - public void insertImageAsBase64(Uri imageURI, String alt,String width, String height) { - InputStream inputStream= null; - try { - inputStream = getContext().getContentResolver().openInputStream(imageURI); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } + public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative) { + InputStream inputStream = null; + try { + inputStream = getContext().getContentResolver().openInputStream(imageURI); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } - Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } - //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); - String format="png"; - String tag = "data:image/" + format + ";charset=utf-8;base64,"; - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "','"+ alt + "','" + width + "', '" + height + "');"); - //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); - } + String type = getContext().getContentResolver().getType(imageURI).toLowerCase(); + String tag = "data:" + type + ";charset=utf-8;base64,"; + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, type) + "','" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); + //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); + } /** * {@link RichEditor#insertVideo(String, String, String, String)} will show the original size of the video. diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java index 1752ca0..6286a4d 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java @@ -34,12 +34,12 @@ private Utils() throws InstantiationException { public static String toBase64(Bitmap bitmap, String type) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - if (type.equals("jpg") || type.equals("jpeg") ) - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); - else if(type.equals("png")) - bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); - else if(type.equals("webp")) - bitmap.compress(Bitmap.CompressFormat.WEBP, 100, baos); + if (type.contains("jpg") || type.contains("jpeg")) + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); + else if (type.contains("png")) + bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); + else if (type.contains("webp")) + bitmap.compress(Bitmap.CompressFormat.WEBP, 100, baos); return Base64.encodeToString(baos.toByteArray(), Base64.NO_WRAP); } From d79c0a21f5adf876ab72129ed659c168494fff8b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 29 Apr 2023 13:13:46 +0200 Subject: [PATCH 077/136] merge fixes signed-off-by: niendo1 Signed-off-by: niendo1 --- .../jp/wasabeef/richeditor/RichEditor.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 22768eb..464cf0c 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -507,26 +507,27 @@ public void insertImage(String url, String alt, String width, String height, Boo exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); } - public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative) { - InputStream inputStream = null; - try { - inputStream = getContext().getContentResolver().openInputStream(imageURI); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } + public void insertImageAsBase64(Uri imageURI, String alt, String width, String height) { + InputStream inputStream = null; + try { + inputStream = getContext().getContentResolver().openInputStream(imageURI); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } - Bitmap bitmap = BitmapFactory.decodeStream(inputStream); - try { - inputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - String type = getContext().getContentResolver().getType(imageURI).toLowerCase(); - String tag = "data:" + type + ";charset=utf-8;base64,"; - exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, type) + "','" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); - //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); } + //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); + String format = "png"; + String tag = "data:image/" + format + ";charset=utf-8;base64,"; + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "','" + alt + "','" + width + "', '" + height + "');"); + //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); + } /** * {@link RichEditor#insertVideo(String, String, String, String)} will show the original size of the video. From 063b0cdc66b9d3a7094ea16d78088056540245ce Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 29 Apr 2023 13:21:37 +0200 Subject: [PATCH 078/136] some git geraffel signed-off-by: niendo1 Signed-off-by: niendo1 --- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 464cf0c..4b9a0e2 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -507,7 +507,7 @@ public void insertImage(String url, String alt, String width, String height, Boo exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); } - public void insertImageAsBase64(Uri imageURI, String alt, String width, String height) { + public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative) { InputStream inputStream = null; try { inputStream = getContext().getContentResolver().openInputStream(imageURI); @@ -521,11 +521,10 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h } catch (IOException e) { e.printStackTrace(); } - //String format = getContext().getContentResolver().getType(imageURI).toLowerCase(); - String format = "png"; - String tag = "data:image/" + format + ";charset=utf-8;base64,"; + String type = getContext().getContentResolver().getType(imageURI).toLowerCase(); + String tag = "data:" + type + ";charset=utf-8;base64,"; exec("javascript:RE.prepareInsert();"); - exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, format) + "','" + alt + "','" + width + "', '" + height + "');"); + exec("javascript:RE.insertImage('" + tag + Utils.toBase64(bitmap, type) + "','" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); //exec("javascript:RE.insertImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==','alt');"); } From 6d2073c1758b14ad081108af502f52035f7b9175 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 6 May 2023 21:51:29 +0200 Subject: [PATCH 079/136] fix image scale signed-off-by: niendo1 Signed-off-by: niendo1 --- richeditor/src/main/assets/rich_editor.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index f63eaac..5078eef 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -453,8 +453,10 @@ RE.insertImage = function(url, alt="", width="", height="", relative="false") { if (alt != "") img.setAttribute("alt", alt); if (relative == "true") { if (width == "") width = "100"; - if (height == "") height = width; - img.setAttribute("style","width: "+width+"%; height: "+height+"%"); + if (height == "") + img.setAttribute("style","width: "+width+"%;"); + else + img.setAttribute("style","width: "+width+"%; height: "+height+"%"); } else { if (width != "") img.setAttribute("width", width); From d48de7aa35d8d8a7687e09af6a7a0ae10511300e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 7 May 2023 20:57:54 +0200 Subject: [PATCH 080/136] insertImageAsBase64() shrinking optional signed-off-by: niendo1 Signed-off-by: niendo1 --- .../java/jp/wasabeef/richeditor/RichEditor.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 4b9a0e2..1588f7c 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -507,7 +507,18 @@ public void insertImage(String url, String alt, String width, String height, Boo exec("javascript:RE.insertImage('" + url + "', '" + alt + "','" + width + "', '" + height + "', '" + relative.toString() + "');"); } - public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative) { + /** + * {@link RichEditor#insertImageAsBase64(Uri, String, String, String, Boolean, Integer)} will show the original size of the image. + * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. + * + * @param imageURI + * @param alt + * @param width Width of the Image; if relative=true then 100 means 100% page width + * @param height Height of the Image + * @param relative Image size is relative to page width + * @param inSampleSize Shrink Image size + */ + public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative, Integer inSampleSize) { InputStream inputStream = null; try { inputStream = getContext().getContentResolver().openInputStream(imageURI); @@ -515,7 +526,9 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h e.printStackTrace(); } - Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = inSampleSize; + Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options); try { inputStream.close(); } catch (IOException e) { From 142d9e98ac47543553fc75a257a35e0fbbcd66ae Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 15 Dec 2023 20:19:51 +0100 Subject: [PATCH 081/136] niendo1 --- build.gradle | 2 +- gradle.properties | 4 +-- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 5 ++-- gradlew | 35 ++++++++++++++--------- gradlew.bat | 1 + 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index c1546a6..5a12b10 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.0.0' + classpath 'com.android.tools.build:gradle:8.2.0' } } diff --git a/gradle.properties b/gradle.properties index 37cbe9e..f75779d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,10 +23,10 @@ VERSION_NAME=3.0.0pre VERSION_CODE=299 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android -COMPILE_SDK_VERSION=33 +COMPILE_SDK_VERSION=34 TARGET_SDK_VERSION=33 MIN_SDK_VERSION=24 -android.defaults.buildfeatures.buildconfig=true +#android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false android.nonFinalResIds=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 zcma&NWl&^owk(X(xVyW%ySuwf;qI=D6|RlDJ2cR^yEKh!@I- zp9QeisK*rlxC>+~7Dk4IxIRsKBHqdR9b3+fyL=ynHmIDe&|>O*VlvO+%z5;9Z$|DJ zb4dO}-R=MKr^6EKJiOrJdLnCJn>np?~vU-1sSFgPu;pthGwf}bG z(1db%xwr#x)r+`4AGu$j7~u2MpVs3VpLp|mx&;>`0p0vH6kF+D2CY0fVdQOZ@h;A` z{infNyvmFUiu*XG}RNMNwXrbec_*a3N=2zJ|Wh5z* z5rAX$JJR{#zP>KY**>xHTuw?|-Rg|o24V)74HcfVT;WtQHXlE+_4iPE8QE#DUm%x0 zEKr75ur~W%w#-My3Tj`hH6EuEW+8K-^5P62$7Sc5OK+22qj&Pd1;)1#4tKihi=~8C zHiQSst0cpri6%OeaR`PY>HH_;CPaRNty%WTm4{wDK8V6gCZlG@U3$~JQZ;HPvDJcT1V{ z?>H@13MJcCNe#5z+MecYNi@VT5|&UiN1D4ATT+%M+h4c$t;C#UAs3O_q=GxK0}8%8 z8J(_M9bayxN}69ex4dzM_P3oh@ZGREjVvn%%r7=xjkqxJP4kj}5tlf;QosR=%4L5y zWhgejO=vao5oX%mOHbhJ8V+SG&K5dABn6!WiKl{|oPkq(9z8l&Mm%(=qGcFzI=eLu zWc_oCLyf;hVlB@dnwY98?75B20=n$>u3b|NB28H0u-6Rpl((%KWEBOfElVWJx+5yg z#SGqwza7f}$z;n~g%4HDU{;V{gXIhft*q2=4zSezGK~nBgu9-Q*rZ#2f=Q}i2|qOp z!!y4p)4o=LVUNhlkp#JL{tfkhXNbB=Ox>M=n6soptJw-IDI|_$is2w}(XY>a=H52d z3zE$tjPUhWWS+5h=KVH&uqQS=$v3nRs&p$%11b%5qtF}S2#Pc`IiyBIF4%A!;AVoI zXU8-Rpv!DQNcF~(qQnyyMy=-AN~U>#&X1j5BLDP{?K!%h!;hfJI>$mdLSvktEr*89 zdJHvby^$xEX0^l9g$xW-d?J;L0#(`UT~zpL&*cEh$L|HPAu=P8`OQZV!-}l`noSp_ zQ-1$q$R-gDL)?6YaM!=8H=QGW$NT2SeZlb8PKJdc=F-cT@j7Xags+Pr*jPtlHFnf- zh?q<6;)27IdPc^Wdy-mX%2s84C1xZq9Xms+==F4);O`VUASmu3(RlgE#0+#giLh-& zcxm3_e}n4{%|X zJp{G_j+%`j_q5}k{eW&TlP}J2wtZ2^<^E(O)4OQX8FDp6RJq!F{(6eHWSD3=f~(h} zJXCf7=r<16X{pHkm%yzYI_=VDP&9bmI1*)YXZeB}F? z(%QsB5fo*FUZxK$oX~X^69;x~j7ms8xlzpt-T15e9}$4T-pC z6PFg@;B-j|Ywajpe4~bk#S6(fO^|mm1hKOPfA%8-_iGCfICE|=P_~e;Wz6my&)h_~ zkv&_xSAw7AZ%ThYF(4jADW4vg=oEdJGVOs>FqamoL3Np8>?!W#!R-0%2Bg4h?kz5I zKV-rKN2n(vUL%D<4oj@|`eJ>0i#TmYBtYmfla;c!ATW%;xGQ0*TW@PTlGG><@dxUI zg>+3SiGdZ%?5N=8uoLA|$4isK$aJ%i{hECP$bK{J#0W2gQ3YEa zZQ50Stn6hqdfxJ*9#NuSLwKFCUGk@c=(igyVL;;2^wi4o30YXSIb2g_ud$ zgpCr@H0qWtk2hK8Q|&wx)}4+hTYlf;$a4#oUM=V@Cw#!$(nOFFpZ;0lc!qd=c$S}Z zGGI-0jg~S~cgVT=4Vo)b)|4phjStD49*EqC)IPwyeKBLcN;Wu@Aeph;emROAwJ-0< z_#>wVm$)ygH|qyxZaet&(Vf%pVdnvKWJn9`%DAxj3ot;v>S$I}jJ$FLBF*~iZ!ZXE zkvui&p}fI0Y=IDX)mm0@tAd|fEHl~J&K}ZX(Mm3cm1UAuwJ42+AO5@HwYfDH7ipIc zmI;1J;J@+aCNG1M`Btf>YT>~c&3j~Qi@Py5JT6;zjx$cvOQW@3oQ>|}GH?TW-E z1R;q^QFjm5W~7f}c3Ww|awg1BAJ^slEV~Pk`Kd`PS$7;SqJZNj->it4DW2l15}xP6 zoCl$kyEF%yJni0(L!Z&14m!1urXh6Btj_5JYt1{#+H8w?5QI%% zo-$KYWNMJVH?Hh@1n7OSu~QhSswL8x0=$<8QG_zepi_`y_79=nK=_ZP_`Em2UI*tyQoB+r{1QYZCpb?2OrgUw#oRH$?^Tj!Req>XiE#~B|~ z+%HB;=ic+R@px4Ld8mwpY;W^A%8%l8$@B@1m5n`TlKI6bz2mp*^^^1mK$COW$HOfp zUGTz-cN9?BGEp}5A!mDFjaiWa2_J2Iq8qj0mXzk; z66JBKRP{p%wN7XobR0YjhAuW9T1Gw3FDvR5dWJ8ElNYF94eF3ebu+QwKjtvVu4L zI9ip#mQ@4uqVdkl-TUQMb^XBJVLW(-$s;Nq;@5gr4`UfLgF$adIhd?rHOa%D);whv z=;krPp~@I+-Z|r#s3yCH+c1US?dnm+C*)r{m+86sTJusLdNu^sqLrfWed^ndHXH`m zd3#cOe3>w-ga(Dus_^ppG9AC>Iq{y%%CK+Cro_sqLCs{VLuK=dev>OL1dis4(PQ5R zcz)>DjEkfV+MO;~>VUlYF00SgfUo~@(&9$Iy2|G0T9BSP?&T22>K46D zL*~j#yJ?)^*%J3!16f)@Y2Z^kS*BzwfAQ7K96rFRIh>#$*$_Io;z>ux@}G98!fWR@ zGTFxv4r~v)Gsd|pF91*-eaZ3Qw1MH$K^7JhWIdX%o$2kCbvGDXy)a?@8T&1dY4`;L z4Kn+f%SSFWE_rpEpL9bnlmYq`D!6F%di<&Hh=+!VI~j)2mfil03T#jJ_s?}VV0_hp z7T9bWxc>Jm2Z0WMU?`Z$xE74Gu~%s{mW!d4uvKCx@WD+gPUQ zV0vQS(Ig++z=EHN)BR44*EDSWIyT~R4$FcF*VEY*8@l=218Q05D2$|fXKFhRgBIEE zdDFB}1dKkoO^7}{5crKX!p?dZWNz$m>1icsXG2N+((x0OIST9Zo^DW_tytvlwXGpn zs8?pJXjEG;T@qrZi%#h93?FP$!&P4JA(&H61tqQi=opRzNpm zkrG}$^t9&XduK*Qa1?355wd8G2CI6QEh@Ua>AsD;7oRUNLPb76m4HG3K?)wF~IyS3`fXuNM>${?wmB zpVz;?6_(Fiadfd{vUCBM*_kt$+F3J+IojI;9L(gc9n3{sEZyzR9o!_mOwFC#tQ{Q~ zP3-`#uK#tP3Q7~Q;4H|wjZHO8h7e4IuBxl&vz2w~D8)w=Wtg31zpZhz%+kzSzL*dV zwp@{WU4i;hJ7c2f1O;7Mz6qRKeASoIv0_bV=i@NMG*l<#+;INk-^`5w@}Dj~;k=|}qM1vq_P z|GpBGe_IKq|LNy9SJhKOQ$c=5L{Dv|Q_lZl=-ky*BFBJLW9&y_C|!vyM~rQx=!vun z?rZJQB5t}Dctmui5i31C_;_}CEn}_W%>oSXtt>@kE1=JW*4*v4tPp;O6 zmAk{)m!)}34pTWg8{i>($%NQ(Tl;QC@J@FfBoc%Gr&m560^kgSfodAFrIjF}aIw)X zoXZ`@IsMkc8_=w%-7`D6Y4e*CG8k%Ud=GXhsTR50jUnm+R*0A(O3UKFg0`K;qp1bl z7``HN=?39ic_kR|^R^~w-*pa?Vj#7|e9F1iRx{GN2?wK!xR1GW!qa=~pjJb-#u1K8 zeR?Y2i-pt}yJq;SCiVHODIvQJX|ZJaT8nO+(?HXbLefulKKgM^B(UIO1r+S=7;kLJ zcH}1J=Px2jsh3Tec&v8Jcbng8;V-`#*UHt?hB(pmOipKwf3Lz8rG$heEB30Sg*2rx zV<|KN86$soN(I!BwO`1n^^uF2*x&vJ$2d$>+`(romzHP|)K_KkO6Hc>_dwMW-M(#S zK(~SiXT1@fvc#U+?|?PniDRm01)f^#55;nhM|wi?oG>yBsa?~?^xTU|fX-R(sTA+5 zaq}-8Tx7zrOy#3*JLIIVsBmHYLdD}!0NP!+ITW+Thn0)8SS!$@)HXwB3tY!fMxc#1 zMp3H?q3eD?u&Njx4;KQ5G>32+GRp1Ee5qMO0lZjaRRu&{W<&~DoJNGkcYF<5(Ab+J zgO>VhBl{okDPn78<%&e2mR{jwVCz5Og;*Z;;3%VvoGo_;HaGLWYF7q#jDX=Z#Ml`H z858YVV$%J|e<1n`%6Vsvq7GmnAV0wW4$5qQ3uR@1i>tW{xrl|ExywIc?fNgYlA?C5 zh$ezAFb5{rQu6i7BSS5*J-|9DQ{6^BVQ{b*lq`xS@RyrsJN?-t=MTMPY;WYeKBCNg z^2|pN!Q^WPJuuO4!|P@jzt&tY1Y8d%FNK5xK(!@`jO2aEA*4 zkO6b|UVBipci?){-Ke=+1;mGlND8)6+P;8sq}UXw2hn;fc7nM>g}GSMWu&v&fqh

iViYT=fZ(|3Ox^$aWPp4a8h24tD<|8-!aK0lHgL$N7Efw}J zVIB!7=T$U`ao1?upi5V4Et*-lTG0XvExbf!ya{cua==$WJyVG(CmA6Of*8E@DSE%L z`V^$qz&RU$7G5mg;8;=#`@rRG`-uS18$0WPN@!v2d{H2sOqP|!(cQ@ zUHo!d>>yFArLPf1q`uBvY32miqShLT1B@gDL4XoVTK&@owOoD)OIHXrYK-a1d$B{v zF^}8D3Y^g%^cnvScOSJR5QNH+BI%d|;J;wWM3~l>${fb8DNPg)wrf|GBP8p%LNGN# z3EaIiItgwtGgT&iYCFy9-LG}bMI|4LdmmJt@V@% zb6B)1kc=T)(|L@0;wr<>=?r04N;E&ef+7C^`wPWtyQe(*pD1pI_&XHy|0gIGHMekd zF_*M4yi6J&Z4LQj65)S zXwdM{SwUo%3SbPwFsHgqF@V|6afT|R6?&S;lw=8% z3}@9B=#JI3@B*#4s!O))~z zc>2_4Q_#&+5V`GFd?88^;c1i7;Vv_I*qt!_Yx*n=;rj!82rrR2rQ8u5(Ejlo{15P% zs~!{%XJ>FmJ})H^I9bn^Re&38H{xA!0l3^89k(oU;bZWXM@kn$#aoS&Y4l^-WEn-fH39Jb9lA%s*WsKJQl?n9B7_~P z-XM&WL7Z!PcoF6_D>V@$CvUIEy=+Z&0kt{szMk=f1|M+r*a43^$$B^MidrT0J;RI` z(?f!O<8UZkm$_Ny$Hth1J#^4ni+im8M9mr&k|3cIgwvjAgjH z8`N&h25xV#v*d$qBX5jkI|xOhQn!>IYZK7l5#^P4M&twe9&Ey@@GxYMxBZq2e7?`q z$~Szs0!g{2fGcp9PZEt|rdQ6bhAgpcLHPz?f-vB?$dc*!9OL?Q8mn7->bFD2Si60* z!O%y)fCdMSV|lkF9w%x~J*A&srMyYY3{=&$}H zGQ4VG_?$2X(0|vT0{=;W$~icCI{b6W{B!Q8xdGhF|D{25G_5_+%s(46lhvNLkik~R z>nr(&C#5wwOzJZQo9m|U<;&Wk!_#q|V>fsmj1g<6%hB{jGoNUPjgJslld>xmODzGjYc?7JSuA?A_QzjDw5AsRgi@Y|Z0{F{!1=!NES-#*f^s4l0Hu zz468))2IY5dmD9pa*(yT5{EyP^G>@ZWumealS-*WeRcZ}B%gxq{MiJ|RyX-^C1V=0 z@iKdrGi1jTe8Ya^x7yyH$kBNvM4R~`fbPq$BzHum-3Zo8C6=KW@||>zsA8-Y9uV5V z#oq-f5L5}V<&wF4@X@<3^C%ptp6+Ce)~hGl`kwj)bsAjmo_GU^r940Z-|`<)oGnh7 zFF0Tde3>ui?8Yj{sF-Z@)yQd~CGZ*w-6p2U<8}JO-sRsVI5dBji`01W8A&3$?}lxBaC&vn0E$c5tW* zX>5(zzZ=qn&!J~KdsPl;P@bmA-Pr8T*)eh_+Dv5=Ma|XSle6t(k8qcgNyar{*ReQ8 zTXwi=8vr>!3Ywr+BhggHDw8ke==NTQVMCK`$69fhzEFB*4+H9LIvdt-#IbhZvpS}} zO3lz;P?zr0*0$%-Rq_y^k(?I{Mk}h@w}cZpMUp|ucs55bcloL2)($u%mXQw({Wzc~ z;6nu5MkjP)0C(@%6Q_I_vsWrfhl7Zpoxw#WoE~r&GOSCz;_ro6i(^hM>I$8y>`!wW z*U^@?B!MMmb89I}2(hcE4zN2G^kwyWCZp5JG>$Ez7zP~D=J^LMjSM)27_0B_X^C(M z`fFT+%DcKlu?^)FCK>QzSnV%IsXVcUFhFdBP!6~se&xxrIxsvySAWu++IrH;FbcY$ z2DWTvSBRfLwdhr0nMx+URA$j3i7_*6BWv#DXfym?ZRDcX9C?cY9sD3q)uBDR3uWg= z(lUIzB)G$Hr!){>E{s4Dew+tb9kvToZp-1&c?y2wn@Z~(VBhqz`cB;{E4(P3N2*nJ z_>~g@;UF2iG{Kt(<1PyePTKahF8<)pozZ*xH~U-kfoAayCwJViIrnqwqO}7{0pHw$ zs2Kx?s#vQr7XZ264>5RNKSL8|Ty^=PsIx^}QqOOcfpGUU4tRkUc|kc7-!Ae6!+B{o~7nFpm3|G5^=0#Bnm6`V}oSQlrX(u%OWnC zoLPy&Q;1Jui&7ST0~#+}I^&?vcE*t47~Xq#YwvA^6^} z`WkC)$AkNub|t@S!$8CBlwbV~?yp&@9h{D|3z-vJXgzRC5^nYm+PyPcgRzAnEi6Q^gslXYRv4nycsy-SJu?lMps-? zV`U*#WnFsdPLL)Q$AmD|0`UaC4ND07+&UmOu!eHruzV|OUox<+Jl|Mr@6~C`T@P%s zW7sgXLF2SSe9Fl^O(I*{9wsFSYb2l%-;&Pi^dpv!{)C3d0AlNY6!4fgmSgj_wQ*7Am7&$z;Jg&wgR-Ih;lUvWS|KTSg!&s_E9_bXBkZvGiC6bFKDWZxsD$*NZ#_8bl zG1P-#@?OQzED7@jlMJTH@V!6k;W>auvft)}g zhoV{7$q=*;=l{O>Q4a@ ziMjf_u*o^PsO)#BjC%0^h>Xp@;5$p{JSYDt)zbb}s{Kbt!T*I@Pk@X0zds6wsefuU zW$XY%yyRGC94=6mf?x+bbA5CDQ2AgW1T-jVAJbm7K(gp+;v6E0WI#kuACgV$r}6L? zd|Tj?^%^*N&b>Dd{Wr$FS2qI#Ucs1yd4N+RBUQiSZGujH`#I)mG&VKoDh=KKFl4=G z&MagXl6*<)$6P}*Tiebpz5L=oMaPrN+caUXRJ`D?=K9!e0f{@D&cZLKN?iNP@X0aF zE(^pl+;*T5qt?1jRC=5PMgV!XNITRLS_=9{CJExaQj;lt!&pdzpK?8p>%Mb+D z?yO*uSung=-`QQ@yX@Hyd4@CI^r{2oiu`%^bNkz+Nkk!IunjwNC|WcqvX~k=><-I3 zDQdbdb|!v+Iz01$w@aMl!R)koD77Xp;eZwzSl-AT zr@Vu{=xvgfq9akRrrM)}=!=xcs+U1JO}{t(avgz`6RqiiX<|hGG1pmop8k6Q+G_mv zJv|RfDheUp2L3=^C=4aCBMBn0aRCU(DQwX-W(RkRwmLeuJYF<0urcaf(=7)JPg<3P zQs!~G)9CT18o!J4{zX{_e}4eS)U-E)0FAt}wEI(c0%HkxgggW;(1E=>J17_hsH^sP z%lT0LGgbUXHx-K*CI-MCrP66UP0PvGqM$MkeLyqHdbgP|_Cm!7te~b8p+e6sQ_3k| zVcwTh6d83ltdnR>D^)BYQpDKlLk3g0Hdcgz2}%qUs9~~Rie)A-BV1mS&naYai#xcZ z(d{8=-LVpTp}2*y)|gR~;qc7fp26}lPcLZ#=JpYcn3AT9(UIdOyg+d(P5T7D&*P}# zQCYplZO5|7+r19%9e`v^vfSS1sbX1c%=w1;oyruXB%Kl$ACgKQ6=qNWLsc=28xJjg zwvsI5-%SGU|3p>&zXVl^vVtQT3o-#$UT9LI@Npz~6=4!>mc431VRNN8od&Ul^+G_kHC`G=6WVWM z%9eWNyy(FTO|A+@x}Ou3CH)oi;t#7rAxdIXfNFwOj_@Y&TGz6P_sqiB`Q6Lxy|Q{`|fgmRG(k+!#b*M+Z9zFce)f-7;?Km5O=LHV9f9_87; zF7%R2B+$?@sH&&-$@tzaPYkw0;=i|;vWdI|Wl3q_Zu>l;XdIw2FjV=;Mq5t1Q0|f< zs08j54Bp`3RzqE=2enlkZxmX6OF+@|2<)A^RNQpBd6o@OXl+i)zO%D4iGiQNuXd+zIR{_lb96{lc~bxsBveIw6umhShTX+3@ZJ=YHh@ zWY3(d0azg;7oHn>H<>?4@*RQbi>SmM=JrHvIG(~BrvI)#W(EAeO6fS+}mxxcc+X~W6&YVl86W9WFSS}Vz-f9vS?XUDBk)3TcF z8V?$4Q)`uKFq>xT=)Y9mMFVTUk*NIA!0$?RP6Ig0TBmUFrq*Q-Agq~DzxjStQyJ({ zBeZ;o5qUUKg=4Hypm|}>>L=XKsZ!F$yNTDO)jt4H0gdQ5$f|d&bnVCMMXhNh)~mN z@_UV6D7MVlsWz+zM+inZZp&P4fj=tm6fX)SG5H>OsQf_I8c~uGCig$GzuwViK54bcgL;VN|FnyQl>Ed7(@>=8$a_UKIz|V6CeVSd2(P z0Uu>A8A+muM%HLFJQ9UZ5c)BSAv_zH#1f02x?h9C}@pN@6{>UiAp>({Fn(T9Q8B z^`zB;kJ5b`>%dLm+Ol}ty!3;8f1XDSVX0AUe5P#@I+FQ-`$(a;zNgz)4x5hz$Hfbg z!Q(z26wHLXko(1`;(BAOg_wShpX0ixfWq3ponndY+u%1gyX)_h=v1zR#V}#q{au6; z!3K=7fQwnRfg6FXtNQmP>`<;!N137paFS%y?;lb1@BEdbvQHYC{976l`cLqn;b8lp zIDY>~m{gDj(wfnK!lpW6pli)HyLEiUrNc%eXTil|F2s(AY+LW5hkKb>TQ3|Q4S9rr zpDs4uK_co6XPsn_z$LeS{K4jFF`2>U`tbgKdyDne`xmR<@6AA+_hPNKCOR-Zqv;xk zu5!HsBUb^!4uJ7v0RuH-7?l?}b=w5lzzXJ~gZcxRKOovSk@|#V+MuX%Y+=;14i*%{)_gSW9(#4%)AV#3__kac1|qUy!uyP{>?U#5wYNq}y$S9pCc zFc~4mgSC*G~j0u#qqp9 z${>3HV~@->GqEhr_Xwoxq?Hjn#=s2;i~g^&Hn|aDKpA>Oc%HlW(KA1?BXqpxB;Ydx)w;2z^MpjJ(Qi(X!$5RC z*P{~%JGDQqojV>2JbEeCE*OEu!$XJ>bWA9Oa_Hd;y)F%MhBRi*LPcdqR8X`NQ&1L# z5#9L*@qxrx8n}LfeB^J{%-?SU{FCwiWyHp682F+|pa+CQa3ZLzBqN1{)h4d6+vBbV zC#NEbQLC;}me3eeYnOG*nXOJZEU$xLZ1<1Y=7r0(-U0P6-AqwMAM`a(Ed#7vJkn6plb4eI4?2y3yOTGmmDQ!z9`wzbf z_OY#0@5=bnep;MV0X_;;SJJWEf^E6Bd^tVJ9znWx&Ks8t*B>AM@?;D4oWUGc z!H*`6d7Cxo6VuyS4Eye&L1ZRhrRmN6Lr`{NL(wDbif|y&z)JN>Fl5#Wi&mMIr5i;x zBx}3YfF>>8EC(fYnmpu~)CYHuHCyr5*`ECap%t@y=jD>!_%3iiE|LN$mK9>- zHdtpy8fGZtkZF?%TW~29JIAfi2jZT8>OA7=h;8T{{k?c2`nCEx9$r zS+*&vt~2o^^J+}RDG@+9&M^K*z4p{5#IEVbz`1%`m5c2};aGt=V?~vIM}ZdPECDI)47|CWBCfDWUbxBCnmYivQ*0Nu_xb*C>~C9(VjHM zxe<*D<#dQ8TlpMX2c@M<9$w!RP$hpG4cs%AI){jp*Sj|*`m)5(Bw*A0$*i-(CA5#%>a)$+jI2C9r6|(>J8InryENI z$NohnxDUB;wAYDwrb*!N3noBTKPpPN}~09SEL18tkG zxgz(RYU_;DPT{l?Q$+eaZaxnsWCA^ds^0PVRkIM%bOd|G2IEBBiz{&^JtNsODs;5z zICt_Zj8wo^KT$7Bg4H+y!Df#3mbl%%?|EXe!&(Vmac1DJ*y~3+kRKAD=Ovde4^^%~ zw<9av18HLyrf*_>Slp;^i`Uy~`mvBjZ|?Ad63yQa#YK`4+c6;pW4?XIY9G1(Xh9WO8{F-Aju+nS9Vmv=$Ac0ienZ+p9*O%NG zMZKy5?%Z6TAJTE?o5vEr0r>f>hb#2w2U3DL64*au_@P!J!TL`oH2r*{>ffu6|A7tv zL4juf$DZ1MW5ZPsG!5)`k8d8c$J$o;%EIL0va9&GzWvkS%ZsGb#S(?{!UFOZ9<$a| zY|a+5kmD5N&{vRqkgY>aHsBT&`rg|&kezoD)gP0fsNYHsO#TRc_$n6Lf1Z{?+DLziXlHrq4sf(!>O{?Tj;Eh@%)+nRE_2VxbN&&%%caU#JDU%vL3}Cb zsb4AazPI{>8H&d=jUaZDS$-0^AxE@utGs;-Ez_F(qC9T=UZX=>ok2k2 ziTn{K?y~a5reD2A)P${NoI^>JXn>`IeArow(41c-Wm~)wiryEP(OS{YXWi7;%dG9v zI?mwu1MxD{yp_rrk!j^cKM)dc4@p4Ezyo%lRN|XyD}}>v=Xoib0gOcdXrQ^*61HNj z=NP|pd>@yfvr-=m{8$3A8TQGMTE7g=z!%yt`8`Bk-0MMwW~h^++;qyUP!J~ykh1GO z(FZ59xuFR$(WE;F@UUyE@Sp>`aVNjyj=Ty>_Vo}xf`e7`F;j-IgL5`1~-#70$9_=uBMq!2&1l zomRgpD58@)YYfvLtPW}{C5B35R;ZVvB<<#)x%srmc_S=A7F@DW8>QOEGwD6suhwCg z>Pa+YyULhmw%BA*4yjDp|2{!T98~<6Yfd(wo1mQ!KWwq0eg+6)o1>W~f~kL<-S+P@$wx*zeI|1t7z#Sxr5 zt6w+;YblPQNplq4Z#T$GLX#j6yldXAqj>4gAnnWtBICUnA&-dtnlh=t0Ho_vEKwV` z)DlJi#!@nkYV#$!)@>udAU*hF?V`2$Hf=V&6PP_|r#Iv*J$9)pF@X3`k;5})9^o4y z&)~?EjX5yX12O(BsFy-l6}nYeuKkiq`u9145&3Ssg^y{5G3Pse z9w(YVa0)N-fLaBq1`P!_#>SS(8fh_5!f{UrgZ~uEdeMJIz7DzI5!NHHqQtm~#CPij z?=N|J>nPR6_sL7!f4hD_|KH`vf8(Wpnj-(gPWH+ZvID}%?~68SwhPTC3u1_cB`otq z)U?6qo!ZLi5b>*KnYHWW=3F!p%h1;h{L&(Q&{qY6)_qxNfbP6E3yYpW!EO+IW3?@J z);4>g4gnl^8klu7uA>eGF6rIGSynacogr)KUwE_R4E5Xzi*Qir@b-jy55-JPC8c~( zo!W8y9OGZ&`xmc8;=4-U9=h{vCqfCNzYirONmGbRQlR`WWlgnY+1wCXbMz&NT~9*| z6@FrzP!LX&{no2!Ln_3|I==_4`@}V?4a;YZKTdw;vT<+K+z=uWbW(&bXEaWJ^W8Td z-3&1bY^Z*oM<=M}LVt>_j+p=2Iu7pZmbXrhQ_k)ysE9yXKygFNw$5hwDn(M>H+e1&9BM5!|81vd%r%vEm zqxY3?F@fb6O#5UunwgAHR9jp_W2zZ}NGp2%mTW@(hz7$^+a`A?mb8|_G*GNMJ) zjqegXQio=i@AINre&%ofexAr95aop5C+0MZ0m-l=MeO8m3epm7U%vZB8+I+C*iNFM z#T3l`gknX;D$-`2XT^Cg*vrv=RH+P;_dfF++cP?B_msQI4j+lt&rX2)3GaJx%W*Nn zkML%D{z5tpHH=dksQ*gzc|}gzW;lwAbxoR07VNgS*-c3d&8J|;@3t^ zVUz*J*&r7DFRuFVDCJDK8V9NN5hvpgGjwx+5n)qa;YCKe8TKtdnh{I7NU9BCN!0dq zczrBk8pE{{@vJa9ywR@mq*J=v+PG;?fwqlJVhijG!3VmIKs>9T6r7MJpC)m!Tc#>g zMtVsU>wbwFJEfwZ{vB|ZlttNe83)$iz`~#8UJ^r)lJ@HA&G#}W&ZH*;k{=TavpjWE z7hdyLZPf*X%Gm}i`Y{OGeeu^~nB8=`{r#TUrM-`;1cBvEd#d!kPqIgYySYhN-*1;L z^byj%Yi}Gx)Wnkosi337BKs}+5H5dth1JA{Ir-JKN$7zC)*}hqeoD(WfaUDPT>0`- z(6sa0AoIqASwF`>hP}^|)a_j2s^PQn*qVC{Q}htR z5-)duBFXT_V56-+UohKXlq~^6uf!6sA#ttk1o~*QEy_Y-S$gAvq47J9Vtk$5oA$Ct zYhYJ@8{hsC^98${!#Ho?4y5MCa7iGnfz}b9jE~h%EAAv~Qxu)_rAV;^cygV~5r_~?l=B`zObj7S=H=~$W zPtI_m%g$`kL_fVUk9J@>EiBH zOO&jtn~&`hIFMS5S`g8w94R4H40mdNUH4W@@XQk1sr17b{@y|JB*G9z1|CrQjd+GX z6+KyURG3;!*BQrentw{B2R&@2&`2}n(z-2&X7#r!{yg@Soy}cRD~j zj9@UBW+N|4HW4AWapy4wfUI- zZ`gSL6DUlgj*f1hSOGXG0IVH8HxK?o2|3HZ;KW{K+yPAlxtb)NV_2AwJm|E)FRs&& z=c^e7bvUsztY|+f^k7NXs$o1EUq>cR7C0$UKi6IooHWlK_#?IWDkvywnzg&ThWo^? z2O_N{5X39#?eV9l)xI(>@!vSB{DLt*oY!K1R8}_?%+0^C{d9a%N4 zoxHVT1&Lm|uDX%$QrBun5e-F`HJ^T$ zmzv)p@4ZHd_w9!%Hf9UYNvGCw2TTTbrj9pl+T9%-_-}L(tES>Or-}Z4F*{##n3~L~TuxjirGuIY#H7{%$E${?p{Q01 zi6T`n;rbK1yIB9jmQNycD~yZq&mbIsFWHo|ZAChSFPQa<(%d8mGw*V3fh|yFoxOOiWJd(qvVb!Z$b88cg->N=qO*4k~6;R==|9ihg&riu#P~s4Oap9O7f%crSr^rljeIfXDEg>wi)&v*a%7zpz<9w z*r!3q9J|390x`Zk;g$&OeN&ctp)VKRpDSV@kU2Q>jtok($Y-*x8_$2piTxun81@vt z!Vj?COa0fg2RPXMSIo26T=~0d`{oGP*eV+$!0I<(4azk&Vj3SiG=Q!6mX0p$z7I}; z9BJUFgT-K9MQQ-0@Z=^7R<{bn2Fm48endsSs`V7_@%8?Bxkqv>BDoVcj?K#dV#uUP zL1ND~?D-|VGKe3Rw_7-Idpht>H6XRLh*U7epS6byiGvJpr%d}XwfusjH9g;Z98H`x zyde%%5mhGOiL4wljCaWCk-&uE4_OOccb9c!ZaWt4B(wYl!?vyzl%7n~QepN&eFUrw zFIOl9c({``6~QD+43*_tzP{f2x41h(?b43^y6=iwyB)2os5hBE!@YUS5?N_tXd=h( z)WE286Fbd>R4M^P{!G)f;h<3Q>Fipuy+d2q-)!RyTgt;wr$(?9ox3;q+{E*ZQHhOn;lM`cjnu9 zXa48ks-v(~b*;MAI<>YZH(^NV8vjb34beE<_cwKlJoR;k6lJNSP6v}uiyRD?|0w+X@o1ONrH8a$fCxXpf? z?$DL0)7|X}Oc%h^zrMKWc-NS9I0Utu@>*j}b@tJ=ixQSJ={4@854wzW@E>VSL+Y{i z#0b=WpbCZS>kUCO_iQz)LoE>P5LIG-hv9E+oG}DtlIDF>$tJ1aw9^LuhLEHt?BCj& z(O4I8v1s#HUi5A>nIS-JK{v!7dJx)^Yg%XjNmlkWAq2*cv#tHgz`Y(bETc6CuO1VkN^L-L3j_x<4NqYb5rzrLC-7uOv z!5e`GZt%B782C5-fGnn*GhDF$%(qP<74Z}3xx+{$4cYKy2ikxI7B2N+2r07DN;|-T->nU&!=Cm#rZt%O_5c&1Z%nlWq3TKAW0w zQqemZw_ue--2uKQsx+niCUou?HjD`xhEjjQd3%rrBi82crq*~#uA4+>vR<_S{~5ce z-2EIl?~s z1=GVL{NxP1N3%=AOaC}j_Fv=ur&THz zyO!d9kHq|c73kpq`$+t+8Bw7MgeR5~`d7ChYyGCBWSteTB>8WAU(NPYt2Dk`@#+}= zI4SvLlyk#pBgVigEe`?NG*vl7V6m+<}%FwPV=~PvvA)=#ths==DRTDEYh4V5}Cf$z@#;< zyWfLY_5sP$gc3LLl2x+Ii)#b2nhNXJ{R~vk`s5U7Nyu^3yFg&D%Txwj6QezMX`V(x z=C`{76*mNb!qHHs)#GgGZ_7|vkt9izl_&PBrsu@}L`X{95-2jf99K)0=*N)VxBX2q z((vkpP2RneSIiIUEnGb?VqbMb=Zia+rF~+iqslydE34cSLJ&BJW^3knX@M;t*b=EA zNvGzv41Ld_T+WT#XjDB840vovUU^FtN_)G}7v)1lPetgpEK9YS^OWFkPoE{ovj^=@ zO9N$S=G$1ecndT_=5ehth2Lmd1II-PuT~C9`XVePw$y8J#dpZ?Tss<6wtVglm(Ok7 z3?^oi@pPio6l&!z8JY(pJvG=*pI?GIOu}e^EB6QYk$#FJQ%^AIK$I4epJ+9t?KjqA+bkj&PQ*|vLttme+`9G=L% ziadyMw_7-M)hS(3E$QGNCu|o23|%O+VN7;Qggp?PB3K-iSeBa2b}V4_wY`G1Jsfz4 z9|SdB^;|I8E8gWqHKx!vj_@SMY^hLEIbSMCuE?WKq=c2mJK z8LoG-pnY!uhqFv&L?yEuxo{dpMTsmCn)95xanqBrNPTgXP((H$9N${Ow~Is-FBg%h z53;|Y5$MUN)9W2HBe2TD`ct^LHI<(xWrw}$qSoei?}s)&w$;&!14w6B6>Yr6Y8b)S z0r71`WmAvJJ`1h&poLftLUS6Ir zC$bG9!Im_4Zjse)#K=oJM9mHW1{%l8sz$1o?ltdKlLTxWWPB>Vk22czVt|1%^wnN@*!l)}?EgtvhC>vlHm^t+ogpgHI1_$1ox9e;>0!+b(tBrmXRB`PY1vp-R**8N7 zGP|QqI$m(Rdu#=(?!(N}G9QhQ%o!aXE=aN{&wtGP8|_qh+7a_j_sU5|J^)vxq;# zjvzLn%_QPHZZIWu1&mRAj;Sa_97p_lLq_{~j!M9N^1yp3U_SxRqK&JnR%6VI#^E12 z>CdOVI^_9aPK2eZ4h&^{pQs}xsijXgFYRIxJ~N7&BB9jUR1fm!(xl)mvy|3e6-B3j zJn#ajL;bFTYJ2+Q)tDjx=3IklO@Q+FFM}6UJr6km7hj7th9n_&JR7fnqC!hTZoM~T zBeaVFp%)0cbPhejX<8pf5HyRUj2>aXnXBqDJe73~J%P(2C?-RT{c3NjE`)om! zl$uewSgWkE66$Kb34+QZZvRn`fob~Cl9=cRk@Es}KQm=?E~CE%spXaMO6YmrMl%9Q zlA3Q$3|L1QJ4?->UjT&CBd!~ru{Ih^in&JXO=|<6J!&qp zRe*OZ*cj5bHYlz!!~iEKcuE|;U4vN1rk$xq6>bUWD*u(V@8sG^7>kVuo(QL@Ki;yL zWC!FT(q{E8#on>%1iAS0HMZDJg{Z{^!De(vSIq&;1$+b)oRMwA3nc3mdTSG#3uYO_ z>+x;7p4I;uHz?ZB>dA-BKl+t-3IB!jBRgdvAbW!aJ(Q{aT>+iz?91`C-xbe)IBoND z9_Xth{6?(y3rddwY$GD65IT#f3<(0o#`di{sh2gm{dw*#-Vnc3r=4==&PU^hCv$qd zjw;>i&?L*Wq#TxG$mFIUf>eK+170KG;~+o&1;Tom9}}mKo23KwdEM6UonXgc z!6N(@k8q@HPw{O8O!lAyi{rZv|DpgfU{py+j(X_cwpKqcalcqKIr0kM^%Br3SdeD> zHSKV94Yxw;pjzDHo!Q?8^0bb%L|wC;4U^9I#pd5O&eexX+Im{ z?jKnCcsE|H?{uGMqVie_C~w7GX)kYGWAg%-?8|N_1#W-|4F)3YTDC+QSq1s!DnOML3@d`mG%o2YbYd#jww|jD$gotpa)kntakp#K;+yo-_ZF9qrNZw<%#C zuPE@#3RocLgPyiBZ+R_-FJ_$xP!RzWm|aN)S+{$LY9vvN+IW~Kf3TsEIvP+B9Mtm! zpfNNxObWQpLoaO&cJh5>%slZnHl_Q~(-Tfh!DMz(dTWld@LG1VRF`9`DYKhyNv z2pU|UZ$#_yUx_B_|MxUq^glT}O5Xt(Vm4Mr02><%C)@v;vPb@pT$*yzJ4aPc_FZ3z z3}PLoMBIM>q_9U2rl^sGhk1VUJ89=*?7|v`{!Z{6bqFMq(mYiA?%KbsI~JwuqVA9$H5vDE+VocjX+G^%bieqx->s;XWlKcuv(s%y%D5Xbc9+ zc(_2nYS1&^yL*ey664&4`IoOeDIig}y-E~_GS?m;D!xv5-xwz+G`5l6V+}CpeJDi^ z%4ed$qowm88=iYG+(`ld5Uh&>Dgs4uPHSJ^TngXP_V6fPyl~>2bhi20QB%lSd#yYn zO05?KT1z@?^-bqO8Cg`;ft>ilejsw@2%RR7;`$Vs;FmO(Yr3Fp`pHGr@P2hC%QcA|X&N2Dn zYf`MqXdHi%cGR@%y7Rg7?d3?an){s$zA{!H;Ie5exE#c~@NhQUFG8V=SQh%UxUeiV zd7#UcYqD=lk-}sEwlpu&H^T_V0{#G?lZMxL7ih_&{(g)MWBnCZxtXg znr#}>U^6!jA%e}@Gj49LWG@*&t0V>Cxc3?oO7LSG%~)Y5}f7vqUUnQ;STjdDU}P9IF9d9<$;=QaXc zL1^X7>fa^jHBu_}9}J~#-oz3Oq^JmGR#?GO7b9a(=R@fw@}Q{{@`Wy1vIQ#Bw?>@X z-_RGG@wt|%u`XUc%W{J z>iSeiz8C3H7@St3mOr_mU+&bL#Uif;+Xw-aZdNYUpdf>Rvu0i0t6k*}vwU`XNO2he z%miH|1tQ8~ZK!zmL&wa3E;l?!!XzgV#%PMVU!0xrDsNNZUWKlbiOjzH-1Uoxm8E#r`#2Sz;-o&qcqB zC-O_R{QGuynW14@)7&@yw1U}uP(1cov)twxeLus0s|7ayrtT8c#`&2~Fiu2=R;1_4bCaD=*E@cYI>7YSnt)nQc zohw5CsK%m?8Ack)qNx`W0_v$5S}nO|(V|RZKBD+btO?JXe|~^Qqur%@eO~<8-L^9d z=GA3-V14ng9L29~XJ>a5k~xT2152zLhM*@zlp2P5Eu}bywkcqR;ISbas&#T#;HZSf z2m69qTV(V@EkY(1Dk3`}j)JMo%ZVJ*5eB zYOjIisi+igK0#yW*gBGj?@I{~mUOvRFQR^pJbEbzFxTubnrw(Muk%}jI+vXmJ;{Q6 zrSobKD>T%}jV4Ub?L1+MGOD~0Ir%-`iTnWZN^~YPrcP5y3VMAzQ+&en^VzKEb$K!Q z<7Dbg&DNXuow*eD5yMr+#08nF!;%4vGrJI++5HdCFcGLfMW!KS*Oi@=7hFwDG!h2< zPunUEAF+HncQkbfFj&pbzp|MU*~60Z(|Ik%Tn{BXMN!hZOosNIseT?R;A`W?=d?5X zK(FB=9mZusYahp|K-wyb={rOpdn=@;4YI2W0EcbMKyo~-#^?h`BA9~o285%oY zfifCh5Lk$SY@|2A@a!T2V+{^!psQkx4?x0HSV`(w9{l75QxMk!)U52Lbhn{8ol?S) zCKo*7R(z!uk<6*qO=wh!Pul{(qq6g6xW;X68GI_CXp`XwO zxuSgPRAtM8K7}5E#-GM!*ydOOG_{A{)hkCII<|2=ma*71ci_-}VPARm3crFQjLYV! z9zbz82$|l01mv`$WahE2$=fAGWkd^X2kY(J7iz}WGS z@%MyBEO=A?HB9=^?nX`@nh;7;laAjs+fbo!|K^mE!tOB>$2a_O0y-*uaIn8k^6Y zSbuv;5~##*4Y~+y7Z5O*3w4qgI5V^17u*ZeupVGH^nM&$qmAk|anf*>r zWc5CV;-JY-Z@Uq1Irpb^O`L_7AGiqd*YpGUShb==os$uN3yYvb`wm6d=?T*it&pDk zo`vhw)RZX|91^^Wa_ti2zBFyWy4cJu#g)_S6~jT}CC{DJ_kKpT`$oAL%b^!2M;JgT zM3ZNbUB?}kP(*YYvXDIH8^7LUxz5oE%kMhF!rnPqv!GiY0o}NR$OD=ITDo9r%4E>E0Y^R(rS^~XjWyVI6 zMOR5rPXhTp*G*M&X#NTL`Hu*R+u*QNoiOKg4CtNPrjgH>c?Hi4MUG#I917fx**+pJfOo!zFM&*da&G_x)L(`k&TPI*t3e^{crd zX<4I$5nBQ8Ax_lmNRa~E*zS-R0sxkz`|>7q_?*e%7bxqNm3_eRG#1ae3gtV9!fQpY z+!^a38o4ZGy9!J5sylDxZTx$JmG!wg7;>&5H1)>f4dXj;B+@6tMlL=)cLl={jLMxY zbbf1ax3S4>bwB9-$;SN2?+GULu;UA-35;VY*^9Blx)Jwyb$=U!D>HhB&=jSsd^6yw zL)?a|>GxU!W}ocTC(?-%z3!IUhw^uzc`Vz_g>-tv)(XA#JK^)ZnC|l1`@CdX1@|!| z_9gQ)7uOf?cR@KDp97*>6X|;t@Y`k_N@)aH7gY27)COv^P3ya9I{4z~vUjLR9~z1Z z5=G{mVtKH*&$*t0@}-i_v|3B$AHHYale7>E+jP`ClqG%L{u;*ff_h@)al?RuL7tOO z->;I}>%WI{;vbLP3VIQ^iA$4wl6@0sDj|~112Y4OFjMs`13!$JGkp%b&E8QzJw_L5 zOnw9joc0^;O%OpF$Qp)W1HI!$4BaXX84`%@#^dk^hFp^pQ@rx4g(8Xjy#!X%+X5Jd@fs3amGT`}mhq#L97R>OwT5-m|h#yT_-v@(k$q7P*9X~T*3)LTdzP!*B} z+SldbVWrrwQo9wX*%FyK+sRXTa@O?WM^FGWOE?S`R(0P{<6p#f?0NJvnBia?k^fX2 zNQs7K-?EijgHJY}&zsr;qJ<*PCZUd*x|dD=IQPUK_nn)@X4KWtqoJNHkT?ZWL_hF? zS8lp2(q>;RXR|F;1O}EE#}gCrY~#n^O`_I&?&z5~7N;zL0)3Tup`%)oHMK-^r$NT% zbFg|o?b9w(q@)6w5V%si<$!U<#}s#x@0aX-hP>zwS#9*75VXA4K*%gUc>+yzupTDBOKH8WR4V0pM(HrfbQ&eJ79>HdCvE=F z|J>s;;iDLB^3(9}?biKbxf1$lI!*Z%*0&8UUq}wMyPs_hclyQQi4;NUY+x2qy|0J; zhn8;5)4ED1oHwg+VZF|80<4MrL97tGGXc5Sw$wAI#|2*cvQ=jB5+{AjMiDHmhUC*a zlmiZ`LAuAn_}hftXh;`Kq0zblDk8?O-`tnilIh|;3lZp@F_osJUV9`*R29M?7H{Fy z`nfVEIDIWXmU&YW;NjU8)EJpXhxe5t+scf|VXM!^bBlwNh)~7|3?fWwo_~ZFk(22% zTMesYw+LNx3J-_|DM~`v93yXe=jPD{q;li;5PD?Dyk+b? zo21|XpT@)$BM$%F=P9J19Vi&1#{jM3!^Y&fr&_`toi`XB1!n>sbL%U9I5<7!@?t)~ z;&H%z>bAaQ4f$wIzkjH70;<8tpUoxzKrPhn#IQfS%9l5=Iu))^XC<58D!-O z{B+o5R^Z21H0T9JQ5gNJnqh#qH^na|z92=hONIM~@_iuOi|F>jBh-?aA20}Qx~EpDGElELNn~|7WRXRFnw+Wdo`|# zBpU=Cz3z%cUJ0mx_1($X<40XEIYz(`noWeO+x#yb_pwj6)R(__%@_Cf>txOQ74wSJ z0#F3(zWWaR-jMEY$7C*3HJrohc79>MCUu26mfYN)f4M~4gD`}EX4e}A!U}QV8!S47 z6y-U-%+h`1n`*pQuKE%Av0@)+wBZr9mH}@vH@i{v(m-6QK7Ncf17x_D=)32`FOjjo zg|^VPf5c6-!FxN{25dvVh#fog=NNpXz zfB$o+0jbRkHH{!TKhE709f+jI^$3#v1Nmf80w`@7-5$1Iv_`)W^px8P-({xwb;D0y z7LKDAHgX<84?l!I*Dvi2#D@oAE^J|g$3!)x1Ua;_;<@#l1fD}lqU2_tS^6Ht$1Wl} zBESo7o^)9-Tjuz$8YQSGhfs{BQV6zW7dA?0b(Dbt=UnQs&4zHfe_sj{RJ4uS-vQpC zX;Bbsuju4%!o8?&m4UZU@~ZZjeFF6ex2ss5_60_JS_|iNc+R0GIjH1@Z z=rLT9%B|WWgOrR7IiIwr2=T;Ne?30M!@{%Qf8o`!>=s<2CBpCK_TWc(DX51>e^xh8 z&@$^b6CgOd7KXQV&Y4%}_#uN*mbanXq(2=Nj`L7H7*k(6F8s6{FOw@(DzU`4-*77{ zF+dxpv}%mFpYK?>N_2*#Y?oB*qEKB}VoQ@bzm>ptmVS_EC(#}Lxxx730trt0G)#$b zE=wVvtqOct1%*9}U{q<)2?{+0TzZzP0jgf9*)arV)*e!f`|jgT{7_9iS@e)recI#z zbzolURQ+TOzE!ymqvBY7+5NnAbWxvMLsLTwEbFqW=CPyCsmJ}P1^V30|D5E|p3BC5 z)3|qgw@ra7aXb-wsa|l^in~1_fm{7bS9jhVRkYVO#U{qMp z)Wce+|DJ}4<2gp8r0_xfZpMo#{Hl2MfjLcZdRB9(B(A(f;+4s*FxV{1F|4d`*sRNd zp4#@sEY|?^FIJ;tmH{@keZ$P(sLh5IdOk@k^0uB^BWr@pk6mHy$qf&~rI>P*a;h0C{%oA*i!VjWn&D~O#MxN&f@1Po# zKN+ zrGrkSjcr?^R#nGl<#Q722^wbYcgW@{+6CBS<1@%dPA8HC!~a`jTz<`g_l5N1M@9wn9GOAZ>nqNgq!yOCbZ@1z`U_N`Z>}+1HIZxk*5RDc&rd5{3qjRh8QmT$VyS;jK z;AF+r6XnnCp=wQYoG|rT2@8&IvKq*IB_WvS%nt%e{MCFm`&W*#LXc|HrD?nVBo=(8*=Aq?u$sDA_sC_RPDUiQ+wnIJET8vx$&fxkW~kP9qXKt zozR)@xGC!P)CTkjeWvXW5&@2?)qt)jiYWWBU?AUtzAN}{JE1I)dfz~7$;}~BmQF`k zpn11qmObXwRB8&rnEG*#4Xax3XBkKlw(;tb?Np^i+H8m(Wyz9k{~ogba@laiEk;2! zV*QV^6g6(QG%vX5Um#^sT&_e`B1pBW5yVth~xUs#0}nv?~C#l?W+9Lsb_5)!71rirGvY zTIJ$OPOY516Y|_014sNv+Z8cc5t_V=i>lWV=vNu#!58y9Zl&GsMEW#pPYPYGHQ|;vFvd*9eM==$_=vc7xnyz0~ zY}r??$<`wAO?JQk@?RGvkWVJlq2dk9vB(yV^vm{=NVI8dhsX<)O(#nr9YD?I?(VmQ z^r7VfUBn<~p3()8yOBjm$#KWx!5hRW)5Jl7wY@ky9lNM^jaT##8QGVsYeaVywmpv>X|Xj7gWE1Ezai&wVLt3p)k4w~yrskT-!PR!kiyQlaxl(( zXhF%Q9x}1TMt3~u@|#wWm-Vq?ZerK={8@~&@9r5JW}r#45#rWii};t`{5#&3$W)|@ zbAf2yDNe0q}NEUvq_Quq3cTjcw z@H_;$hu&xllCI9CFDLuScEMg|x{S7GdV8<&Mq=ezDnRZAyX-8gv97YTm0bg=d)(>N z+B2FcqvI9>jGtnK%eO%y zoBPkJTk%y`8TLf4)IXPBn`U|9>O~WL2C~C$z~9|0m*YH<-vg2CD^SX#&)B4ngOSG$ zV^wmy_iQk>dfN@Pv(ckfy&#ak@MLC7&Q6Ro#!ezM*VEh`+b3Jt%m(^T&p&WJ2Oqvj zs-4nq0TW6cv~(YI$n0UkfwN}kg3_fp?(ijSV#tR9L0}l2qjc7W?i*q01=St0eZ=4h zyGQbEw`9OEH>NMuIe)hVwYHsGERWOD;JxEiO7cQv%pFCeR+IyhwQ|y@&^24k+|8fD zLiOWFNJ2&vu2&`Jv96_z-Cd5RLgmeY3*4rDOQo?Jm`;I_(+ejsPM03!ly!*Cu}Cco zrQSrEDHNyzT(D5s1rZq!8#?f6@v6dB7a-aWs(Qk>N?UGAo{gytlh$%_IhyL7h?DLXDGx zgxGEBQoCAWo-$LRvM=F5MTle`M})t3vVv;2j0HZY&G z22^iGhV@uaJh(XyyY%} zd4iH_UfdV#T=3n}(Lj^|n;O4|$;xhu*8T3hR1mc_A}fK}jfZ7LX~*n5+`8N2q#rI$ z@<_2VANlYF$vIH$ zl<)+*tIWW78IIINA7Rr7i{<;#^yzxoLNkXL)eSs=%|P>$YQIh+ea_3k z_s7r4%j7%&*NHSl?R4k%1>Z=M9o#zxY!n8sL5>BO-ZP;T3Gut>iLS@U%IBrX6BA3k z)&@q}V8a{X<5B}K5s(c(LQ=%v1ocr`t$EqqY0EqVjr65usa=0bkf|O#ky{j3)WBR(((L^wmyHRzoWuL2~WTC=`yZ zn%VX`L=|Ok0v7?s>IHg?yArBcync5rG#^+u)>a%qjES%dRZoIyA8gQ;StH z1Ao7{<&}6U=5}4v<)1T7t!J_CL%U}CKNs-0xWoTTeqj{5{?Be$L0_tk>M9o8 zo371}S#30rKZFM{`H_(L`EM9DGp+Mifk&IP|C2Zu_)Ghr4Qtpmkm1osCf@%Z$%t+7 zYH$Cr)Ro@3-QDeQJ8m+x6%;?YYT;k6Z0E-?kr>x33`H%*ueBD7Zx~3&HtWn0?2Wt} zTG}*|v?{$ajzt}xPzV%lL1t-URi8*Zn)YljXNGDb>;!905Td|mpa@mHjIH%VIiGx- zd@MqhpYFu4_?y5N4xiHn3vX&|e6r~Xt> zZG`aGq|yTNjv;9E+Txuoa@A(9V7g?1_T5FzRI;!=NP1Kqou1z5?%X~Wwb{trRfd>i z8&y^H)8YnKyA_Fyx>}RNmQIczT?w2J4SNvI{5J&}Wto|8FR(W;Qw#b1G<1%#tmYzQ zQ2mZA-PAdi%RQOhkHy9Ea#TPSw?WxwL@H@cbkZwIq0B!@ns}niALidmn&W?!Vd4Gj zO7FiuV4*6Mr^2xlFSvM;Cp_#r8UaqIzHJQg_z^rEJw&OMm_8NGAY2)rKvki|o1bH~ z$2IbfVeY2L(^*rMRU1lM5Y_sgrDS`Z??nR2lX;zyR=c%UyGb*%TC-Dil?SihkjrQy~TMv6;BMs7P8il`H7DmpVm@rJ;b)hW)BL)GjS154b*xq-NXq2cwE z^;VP7ua2pxvCmxrnqUYQMH%a%nHmwmI33nJM(>4LznvY*k&C0{8f*%?zggpDgkuz&JBx{9mfb@wegEl2v!=}Sq2Gaty0<)UrOT0{MZtZ~j5y&w zXlYa_jY)I_+VA-^#mEox#+G>UgvM!Ac8zI<%JRXM_73Q!#i3O|)lOP*qBeJG#BST0 zqohi)O!|$|2SeJQo(w6w7%*92S})XfnhrH_Z8qe!G5>CglP=nI7JAOW?(Z29;pXJ9 zR9`KzQ=WEhy*)WH>$;7Cdz|>*i>=##0bB)oU0OR>>N<21e4rMCHDemNi2LD>Nc$;& zQRFthpWniC1J6@Zh~iJCoLOxN`oCKD5Q4r%ynwgUKPlIEd#?QViIqovY|czyK8>6B zSP%{2-<;%;1`#0mG^B(8KbtXF;Nf>K#Di72UWE4gQ%(_26Koiad)q$xRL~?pN71ZZ zujaaCx~jXjygw;rI!WB=xrOJO6HJ!!w}7eiivtCg5K|F6$EXa)=xUC za^JXSX98W`7g-tm@uo|BKj39Dl;sg5ta;4qjo^pCh~{-HdLl6qI9Ix6f$+qiZ$}s= zNguKrU;u+T@ko(Vr1>)Q%h$?UKXCY>3se%&;h2osl2D zE4A9bd7_|^njDd)6cI*FupHpE3){4NQ*$k*cOWZ_?CZ>Z4_fl@n(mMnYK62Q1d@+I zr&O))G4hMihgBqRIAJkLdk(p(D~X{-oBUA+If@B}j& zsHbeJ3RzTq96lB7d($h$xTeZ^gP0c{t!Y0c)aQE;$FY2!mACg!GDEMKXFOPI^)nHZ z`aSPJpvV0|bbrzhWWkuPURlDeN%VT8tndV8?d)eN*i4I@u zVKl^6{?}A?P)Fsy?3oi#clf}L18t;TjNI2>eI&(ezDK7RyqFxcv%>?oxUlonv(px) z$vnPzRH`y5A(x!yOIfL0bmgeMQB$H5wenx~!ujQK*nUBW;@Em&6Xv2%s(~H5WcU2R z;%Nw<$tI)a`Ve!>x+qegJnQsN2N7HaKzrFqM>`6R*gvh%O*-%THt zrB$Nk;lE;z{s{r^PPm5qz(&lM{sO*g+W{sK+m3M_z=4=&CC>T`{X}1Vg2PEfSj2x_ zmT*(x;ov%3F?qoEeeM>dUn$a*?SIGyO8m806J1W1o+4HRhc2`9$s6hM#qAm zChQ87b~GEw{ADfs+5}FJ8+|bIlIv(jT$Ap#hSHoXdd9#w<#cA<1Rkq^*EEkknUd4& zoIWIY)sAswy6fSERVm&!SO~#iN$OgOX*{9@_BWFyJTvC%S++ilSfCrO(?u=Dc?CXZ zzCG&0yVR{Z`|ZF0eEApWEo#s9osV>F{uK{QA@BES#&;#KsScf>y zvs?vIbI>VrT<*!;XmQS=bhq%46-aambZ(8KU-wOO2=en~D}MCToB_u;Yz{)1ySrPZ z@=$}EvjTdzTWU7c0ZI6L8=yP+YRD_eMMos}b5vY^S*~VZysrkq<`cK3>>v%uy7jgq z0ilW9KjVDHLv0b<1K_`1IkbTOINs0=m-22c%M~l=^S}%hbli-3?BnNq?b`hx^HX2J zIe6ECljRL0uBWb`%{EA=%!i^4sMcj+U_TaTZRb+~GOk z^ZW!nky0n*Wb*r+Q|9H@ml@Z5gU&W`(z4-j!OzC1wOke`TRAYGZVl$PmQ16{3196( zO*?`--I}Qf(2HIwb2&1FB^!faPA2=sLg(@6P4mN)>Dc3i(B0;@O-y2;lM4akD>@^v z=u>*|!s&9zem70g7zfw9FXl1bpJW(C#5w#uy5!V?Q(U35A~$dR%LDVnq@}kQm13{} zd53q3N(s$Eu{R}k2esbftfjfOITCL;jWa$}(mmm}d(&7JZ6d3%IABCapFFYjdEjdK z&4Edqf$G^MNAtL=uCDRs&Fu@FXRgX{*0<(@c3|PNHa>L%zvxWS={L8%qw`STm+=Rd zA}FLspESSIpE_^41~#5yI2bJ=9`oc;GIL!JuW&7YetZ?0H}$$%8rW@*J37L-~Rsx!)8($nI4 zZhcZ2^=Y+p4YPl%j!nFJA|*M^gc(0o$i3nlphe+~-_m}jVkRN{spFs(o0ajW@f3K{ zDV!#BwL322CET$}Y}^0ixYj2w>&Xh12|R8&yEw|wLDvF!lZ#dOTHM9pK6@Nm-@9Lnng4ZHBgBSrr7KI8YCC9DX5Kg|`HsiwJHg2(7#nS;A{b3tVO?Z% za{m5b3rFV6EpX;=;n#wltDv1LE*|g5pQ+OY&*6qCJZc5oDS6Z6JD#6F)bWxZSF@q% z+1WV;m!lRB!n^PC>RgQCI#D1br_o^#iPk>;K2hB~0^<~)?p}LG%kigm@moD#q3PE+ zA^Qca)(xnqw6x>XFhV6ku9r$E>bWNrVH9fum0?4s?Rn2LG{Vm_+QJHse6xa%nzQ?k zKug4PW~#Gtb;#5+9!QBgyB@q=sk9=$S{4T>wjFICStOM?__fr+Kei1 z3j~xPqW;W@YkiUM;HngG!;>@AITg}vAE`M2Pj9Irl4w1fo4w<|Bu!%rh%a(Ai^Zhi zs92>v5;@Y(Zi#RI*ua*h`d_7;byQSa*v9E{2x$<-_=5Z<7{%)}4XExANcz@rK69T0x3%H<@frW>RA8^swA+^a(FxK| zFl3LD*ImHN=XDUkrRhp6RY5$rQ{bRgSO*(vEHYV)3Mo6Jy3puiLmU&g82p{qr0F?ohmbz)f2r{X2|T2 z$4fdQ=>0BeKbiVM!e-lIIs8wVTuC_m7}y4A_%ikI;Wm5$9j(^Y z(cD%U%k)X>_>9~t8;pGzL6L-fmQO@K; zo&vQzMlgY95;1BSkngY)e{`n0!NfVgf}2mB3t}D9@*N;FQ{HZ3Pb%BK6;5#-O|WI( zb6h@qTLU~AbVW#_6?c!?Dj65Now7*pU{h!1+eCV^KCuPAGs28~3k@ueL5+u|Z-7}t z9|lskE`4B7W8wMs@xJa{#bsCGDFoRSNSnmNYB&U7 zVGKWe%+kFB6kb)e;TyHfqtU6~fRg)f|>=5(N36)0+C z`hv65J<$B}WUc!wFAb^QtY31yNleq4dzmG`1wHTj=c*=hay9iD071Hc?oYoUk|M*_ zU1GihAMBsM@5rUJ(qS?9ZYJ6@{bNqJ`2Mr+5#hKf?doa?F|+^IR!8lq9)wS3tF_9n zW_?hm)G(M+MYb?V9YoX^_mu5h-LP^TL^!Q9Z7|@sO(rg_4+@=PdI)WL(B7`!K^ND- z-uIuVDCVEdH_C@c71YGYT^_Scf_dhB8Z2Xy6vGtBSlYud9vggOqv^L~F{BraSE_t} zIkP+Hp2&nH^-MNEs}^`oMLy11`PQW$T|K(`Bu*(f@)mv1-qY(_YG&J2M2<7k;;RK~ zL{Fqj9yCz8(S{}@c)S!65aF<=&eLI{hAMErCx&>i7OeDN>okvegO87OaG{Jmi<|}D zaT@b|0X{d@OIJ7zvT>r+eTzgLq~|Dpu)Z&db-P4z*`M$UL51lf>FLlq6rfG)%doyp z)3kk_YIM!03eQ8Vu_2fg{+osaEJPtJ-s36R+5_AEG12`NG)IQ#TF9c@$99%0iye+ zUzZ57=m2)$D(5Nx!n)=5Au&O0BBgwxIBaeI(mro$#&UGCr<;C{UjJVAbVi%|+WP(a zL$U@TYCxJ=1{Z~}rnW;7UVb7+ZnzgmrogDxhjLGo>c~MiJAWs&&;AGg@%U?Y^0JhL ze(x6Z74JG6FlOFK(T}SXQfhr}RIFl@QXKnIcXYF)5|V~e-}suHILKT-k|<*~Ij|VF zC;t@=uj=hot~*!C68G8hTA%8SzOfETOXQ|3FSaIEjvBJp(A)7SWUi5!Eu#yWgY+;n zlm<$+UDou*V+246_o#V4kMdto8hF%%Lki#zPh}KYXmMf?hrN0;>Mv%`@{0Qn`Ujp) z=lZe+13>^Q!9zT);H<(#bIeRWz%#*}sgUX9P|9($kexOyKIOc`dLux}c$7It4u|Rl z6SSkY*V~g_B-hMPo_ak>>z@AVQ(_N)VY2kB3IZ0G(iDUYw+2d7W^~(Jq}KY=JnWS( z#rzEa&0uNhJ>QE8iiyz;n2H|SV#Og+wEZv=f2%1ELX!SX-(d3tEj$5$1}70Mp<&eI zCkfbByL7af=qQE@5vDVxx1}FSGt_a1DoE3SDI+G)mBAna)KBG4p8Epxl9QZ4BfdAN zFnF|Y(umr;gRgG6NLQ$?ZWgllEeeq~z^ZS7L?<(~O&$5|y)Al^iMKy}&W+eMm1W z7EMU)u^ke(A1#XCV>CZ71}P}0x)4wtHO8#JRG3MA-6g=`ZM!FcICCZ{IEw8Dm2&LQ z1|r)BUG^0GzI6f946RrBlfB1Vs)~8toZf~7)+G;pv&XiUO(%5bm)pl=p>nV^o*;&T z;}@oZSibzto$arQgfkp|z4Z($P>dTXE{4O=vY0!)kDO* zGF8a4wq#VaFpLfK!iELy@?-SeRrdz%F*}hjKcA*y@mj~VD3!it9lhRhX}5YOaR9$} z3mS%$2Be7{l(+MVx3 z(4?h;P!jnRmX9J9sYN#7i=iyj_5q7n#X(!cdqI2lnr8T$IfOW<_v`eB!d9xY1P=2q&WtOXY=D9QYteP)De?S4}FK6#6Ma z=E*V+#s8>L;8aVroK^6iKo=MH{4yEZ_>N-N z`(|;aOATba1^asjxlILk<4}f~`39dBFlxj>Dw(hMYKPO3EEt1@S`1lxFNM+J@uB7T zZ8WKjz7HF1-5&2=l=fqF-*@>n5J}jIxdDwpT?oKM3s8Nr`x8JnN-kCE?~aM1H!hAE z%%w(3kHfGwMnMmNj(SU(w42OrC-euI>Dsjk&jz3ts}WHqmMpzQ3vZrsXrZ|}+MHA7 z068obeXZTsO*6RS@o3x80E4ok``rV^Y3hr&C1;|ZZ0|*EKO`$lECUYG2gVFtUTw)R z4Um<0ZzlON`zTdvVdL#KFoMFQX*a5wM0Czp%wTtfK4Sjs)P**RW&?lP$(<}q%r68Z zS53Y!d@&~ne9O)A^tNrXHhXBkj~$8j%pT1%%mypa9AW5E&s9)rjF4@O3ytH{0z6riz|@< zB~UPh*wRFg2^7EbQrHf0y?E~dHlkOxof_a?M{LqQ^C!i2dawHTPYUE=X@2(3<=OOxs8qn_(y>pU>u^}3y&df{JarR0@VJn0f+U%UiF=$Wyq zQvnVHESil@d|8&R<%}uidGh7@u^(%?$#|&J$pvFC-n8&A>utA=n3#)yMkz+qnG3wd zP7xCnF|$9Dif@N~L)Vde3hW8W!UY0BgT2v(wzp;tlLmyk2%N|0jfG$%<;A&IVrOI< z!L)o>j>;dFaqA3pL}b-Je(bB@VJ4%!JeX@3x!i{yIeIso^=n?fDX`3bU=eG7sTc%g%ye8$v8P@yKE^XD=NYxTb zbf!Mk=h|otpqjFaA-vs5YOF-*GwWPc7VbaOW&stlANnCN8iftFMMrUdYNJ_Bnn5Vt zxfz@Ah|+4&P;reZxp;MmEI7C|FOv8NKUm8njF7Wb6Gi7DeODLl&G~}G4be&*Hi0Qw z5}77vL0P+7-B%UL@3n1&JPxW^d@vVwp?u#gVcJqY9#@-3X{ok#UfW3<1fb%FT`|)V~ggq z(3AUoUS-;7)^hCjdT0Kf{i}h)mBg4qhtHHBti=~h^n^OTH5U*XMgDLIR@sre`AaB$ zg)IGBET_4??m@cx&c~bA80O7B8CHR7(LX7%HThkeC*@vi{-pL%e)yXp!B2InafbDF zjPXf1mko3h59{lT6EEbxKO1Z5GF71)WwowO6kY|6tjSVSWdQ}NsK2x{>i|MKZK8%Q zfu&_0D;CO-Jg0#YmyfctyJ!mRJp)e#@O0mYdp|8x;G1%OZQ3Q847YWTyy|%^cpA;m zze0(5p{tMu^lDkpe?HynyO?a1$_LJl2L&mpeKu%8YvgRNr=%2z${%WThHG=vrWY@4 zsA`OP#O&)TetZ>s%h!=+CE15lOOls&nvC~$Qz0Ph7tHiP;O$i|eDwpT{cp>+)0-|; zY$|bB+Gbel>5aRN3>c0x)4U=|X+z+{ zn*_p*EQoquRL+=+p;=lm`d71&1NqBz&_ph)MXu(Nv6&XE7(RsS)^MGj5Q?Fwude-(sq zjJ>aOq!7!EN>@(fK7EE#;i_BGvli`5U;r!YA{JRodLBc6-`n8K+Fjgwb%sX;j=qHQ z7&Tr!)!{HXoO<2BQrV9Sw?JRaLXV8HrsNevvnf>Y-6|{T!pYLl7jp$-nEE z#X!4G4L#K0qG_4Z;Cj6=;b|Be$hi4JvMH!-voxqx^@8cXp`B??eFBz2lLD8RRaRGh zn7kUfy!YV~p(R|p7iC1Rdgt$_24i0cd-S8HpG|`@my70g^y`gu%#Tf_L21-k?sRRZHK&at(*ED0P8iw{7?R$9~OF$Ko;Iu5)ur5<->x!m93Eb zFYpIx60s=Wxxw=`$aS-O&dCO_9?b1yKiPCQmSQb>T)963`*U+Ydj5kI(B(B?HNP8r z*bfSBpSu)w(Z3j7HQoRjUG(+d=IaE~tv}y14zHHs|0UcN52fT8V_<@2ep_ee{QgZG zmgp8iv4V{k;~8@I%M3<#B;2R>Ef(Gg_cQM7%}0s*^)SK6!Ym+~P^58*wnwV1BW@eG z4sZLqsUvBbFsr#8u7S1r4teQ;t)Y@jnn_m5jS$CsW1um!p&PqAcc8!zyiXHVta9QC zY~wCwCF0U%xiQPD_INKtTb;A|Zf29(mu9NI;E zc-e>*1%(LSXB`g}kd`#}O;veb<(sk~RWL|f3ljxCnEZDdNSTDV6#Td({6l&y4IjKF z^}lIUq*ZUqgTPumD)RrCN{M^jhY>E~1pn|KOZ5((%F)G|*ZQ|r4zIbrEiV%42hJV8 z3xS)=!X1+=olbdGJ=yZil?oXLct8FM{(6ikLL3E%=q#O6(H$p~gQu6T8N!plf!96| z&Q3=`L~>U0zZh;z(pGR2^S^{#PrPxTRHD1RQOON&f)Siaf`GLj#UOk&(|@0?zm;Sx ztsGt8=29-MZs5CSf1l1jNFtNt5rFNZxJPvkNu~2}7*9468TWm>nN9TP&^!;J{-h)_ z7WsHH9|F%I`Pb!>KAS3jQWKfGivTVkMJLO-HUGM_a4UQ_%RgL6WZvrW+Z4ujZn;y@ zz9$=oO!7qVTaQAA^BhX&ZxS*|5dj803M=k&2%QrXda`-Q#IoZL6E(g+tN!6CA!CP* zCpWtCujIea)ENl0liwVfj)Nc<9mV%+e@=d`haoZ*`B7+PNjEbXBkv=B+Pi^~L#EO$D$ZqTiD8f<5$eyb54-(=3 zh)6i8i|jp(@OnRrY5B8t|LFXFQVQ895n*P16cEKTrT*~yLH6Z4e*bZ5otpRDri&+A zfNbK1D5@O=sm`fN=WzWyse!za5n%^+6dHPGX#8DyIK>?9qyX}2XvBWVqbP%%D)7$= z=#$WulZlZR<{m#gU7lwqK4WS1Ne$#_P{b17qe$~UOXCl>5b|6WVh;5vVnR<%d+Lnp z$uEmML38}U4vaW8>shm6CzB(Wei3s#NAWE3)a2)z@i{4jTn;;aQS)O@l{rUM`J@K& l00vQ5JBs~;vo!vr%%-k{2_Fq1Mn4QF81S)AQ99zk{{c4yR+0b! literal 60756 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 53a6b23..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% From 97a160ce55ef6034067032a7a97da02d69cd3e01 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 17 Dec 2023 14:51:15 +0100 Subject: [PATCH 082/136] niendo1 --- gradle.properties | 2 +- richeditor/build.gradle | 3 ++- sample/build.gradle | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index f75779d..09f8eeb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ VERSION_NAME=3.0.0pre VERSION_CODE=299 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android -COMPILE_SDK_VERSION=34 +#COMPILE_SDK_VERSION=34 TARGET_SDK_VERSION=33 MIN_SDK_VERSION=24 #android.defaults.buildfeatures.buildconfig=true diff --git a/richeditor/build.gradle b/richeditor/build.gradle index cd2517c..4d25759 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -1,7 +1,8 @@ apply plugin: 'com.android.library' android { - compileSdkVersion COMPILE_SDK_VERSION as int + + compileSdk 34 defaultConfig { minSdkVersion MIN_SDK_VERSION as int diff --git a/sample/build.gradle b/sample/build.gradle index 2f18d6c..61080ed 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion COMPILE_SDK_VERSION as int + compileSdk 34 defaultConfig { minSdkVersion MIN_SDK_VERSION as int @@ -17,12 +17,10 @@ android { buildTypes { debug { debuggable true - zipAlignEnabled true signingConfig signingConfigs.debug } release { debuggable false - zipAlignEnabled true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' shrinkResources true From 39ddf8e58e1ec2d5717045f949de2697871e94c9 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 19:51:19 +0100 Subject: [PATCH 083/136] prepare jitpack niendo1 --- README.md | 19 ++---- build.gradle | 5 ++ gradle.properties | 4 +- richeditor/build.gradle | 67 ++++++++++--------- .../test/java/richeditor/UrlDecoderTest.java | 16 ++--- 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index ff89417..b33f706 100644 --- a/README.md +++ b/README.md @@ -95,23 +95,16 @@ How do I use it? ##### Gradle -~~repositories {~~ - ~~mavenCentral()~~ -~~}~~ - -~~dependencies {~~ - ~~implementation 'jp.wasabeef:richeditor-android:2.0.0'~~ -~~}~~ - -```groovy +repositories { + mavenCentral() + maven { url "https://jitpack.io" } +} dependencies { - implementation files('../../richeditor-android/richeditor/build/outputs/aar/richeditor-debug.aar') + implementation 'com.github.jitpack:richeditor-android:3.0.0' } -settings.gradle - -includeBuild('../richeditor-android') +```groovy ``` diff --git a/build.gradle b/build.gradle index 5a12b10..bdefef2 100644 --- a/build.gradle +++ b/build.gradle @@ -10,9 +10,14 @@ buildscript { } } +//plugins { +// id 'maven-publish' +//} + allprojects { repositories { google() mavenCentral() } } + diff --git a/gradle.properties b/gradle.properties index 09f8eeb..10c22a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0pre -VERSION_CODE=299 +VERSION_NAME=3.0.0pre0 +VERSION_CODE=290 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android #COMPILE_SDK_VERSION=34 diff --git a/richeditor/build.gradle b/richeditor/build.gradle index 4d25759..e3d0b0d 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -1,45 +1,52 @@ -apply plugin: 'com.android.library' +plugins { + id 'com.android.library' +} android { - compileSdk 34 - defaultConfig { minSdkVersion MIN_SDK_VERSION as int targetSdkVersion TARGET_SDK_VERSION as int } namespace 'jp.wasabeef.richeditor' -} + publishing { + singleVariant("release") + } + buildTypes { + release { + debuggable false + minifyEnabled true + } + } +} dependencies { - testImplementation 'junit:junit:4.13.2' + //testImplementation 'junit:junit:4.13.2' //testImplementation 'org.robolectric:robolectric:4.9.2' } -/* -ext { - bintrayRepo = 'maven' - bintrayName = 'richeditor-android' - bintrayUserOrg = 'wasabeef' - publishedGroupId = 'jp.wasabeef' - libraryName = 'richeditor-android' - artifact = 'richeditor-android' - libraryDescription = 'RichEditor for Android is a beautiful Rich Text WYSIWYG Editor' - siteUrl = 'https://github.com/richeditor-android' - gitUrl = 'https://github.com/richeditor-android.git' - issueUrl = 'https://github.com/richeditor-android/issues' - libraryVersion = VERSION_NAME - developerId = 'wasabeef' - developerName = 'Wasabeef' - developerEmail = 'dadadada.chop@gmail.com' - licenseName = 'The Apache Software License, Version 2.0' - licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - allLicenses = ["Apache-2.0"] -} -// TODO: Close JCenter on May 1st https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ -// apply from: 'https://gist.githubusercontent.com/wasabeef/cf14805bee509baf7461974582f17d26/raw/bintray-v1.gradle' -// apply from: 'https://gist.githubusercontent.com/wasabeef/cf14805bee509baf7461974582f17d26/raw/install-v1.gradle' +//afterEvaluate { +// publishing { +// publications { +// release(MavenPublication) { +// from components.release +// groupId = 'com.github.niendo1' //This should be the name of the publishing account +// artifactId = 'richeditor-android' //This is the name you want to use for the published library. +// version = '0.9.0-SNAPSHOT' + +// repositories { +// maven { +// name = "GitHubPackages" +// url = uri("https://maven.pkg.github.com/niendo1/richeditor-android") +// credentials { +// username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") +// password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") +// } +// } +// } +// } +// } +// } +// } -apply from: 'https://gist.githubusercontent.com/wasabeef/2f2ae8d97b429e7d967128125dc47854/raw/maven-central-v1.gradle' -*/ diff --git a/richeditor/src/test/java/richeditor/UrlDecoderTest.java b/richeditor/src/test/java/richeditor/UrlDecoderTest.java index e1ad7fc..fd1c3da 100644 --- a/richeditor/src/test/java/richeditor/UrlDecoderTest.java +++ b/richeditor/src/test/java/richeditor/UrlDecoderTest.java @@ -2,21 +2,21 @@ import android.net.Uri; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +//import org.junit.Assert; +//import org.junit.Test; +//import org.junit.runner.RunWith; //@RunWith(RobolectricTestRunner.class) public class UrlDecoderTest { - @Test + public void urlDecodeTest() throws Exception { - String encoded = "re-callback://%20%20%3Cdiv%3E%3Cfont%20face=%22Arial%22%20size=%222%22%20color=%22#333333%22%3EDJK%20Besteck%3C/font%3E%3Cb%3E%3Cfont%20face=%22Arial%22%20size=%222%22%20color=%22#333333%22%3E Kenntnisse++_%20++ 下 ぁ ص%3C/font%3E%3C/b%3E%3C/div%3E%20"; - String decoded = Uri.decode(encoded); + // String encoded = "re-callback://%20%20%3Cdiv%3E%3Cfont%20face=%22Arial%22%20size=%222%22%20color=%22#333333%22%3EDJK%20Besteck%3C/font%3E%3Cb%3E%3Cfont%20face=%22Arial%22%20size=%222%22%20color=%22#333333%22%3E Kenntnisse++_%20++ 下 ぁ ص%3C/font%3E%3C/b%3E%3C/div%3E%20"; +// String decoded = Uri.decode(encoded); - String test = "re-callback://

DJK Besteck Kenntnisse++_ ++ 下 ぁ ص
"; + // String test = "re-callback://
DJK Besteck Kenntnisse++_ ++ 下 ぁ ص
"; - Assert.assertEquals(test, decoded); + //Assert.assertEquals(test, decoded); } } From d1ff059e4d39074d07373dd7c1fac8c892c15b2b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 19:55:39 +0100 Subject: [PATCH 084/136] prepare jitpack niendo1 --- build.gradle | 6 +++--- richeditor/build.gradle | 44 ++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index bdefef2..758842b 100644 --- a/build.gradle +++ b/build.gradle @@ -10,9 +10,9 @@ buildscript { } } -//plugins { -// id 'maven-publish' -//} +plugins { + id 'maven-publish' +} allprojects { repositories { diff --git a/richeditor/build.gradle b/richeditor/build.gradle index e3d0b0d..6f4ee2c 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -26,27 +26,27 @@ dependencies { //testImplementation 'org.robolectric:robolectric:4.9.2' } -//afterEvaluate { -// publishing { -// publications { -// release(MavenPublication) { -// from components.release -// groupId = 'com.github.niendo1' //This should be the name of the publishing account -// artifactId = 'richeditor-android' //This is the name you want to use for the published library. -// version = '0.9.0-SNAPSHOT' +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + groupId = 'com.github.niendo1' //This should be the name of the publishing account + artifactId = 'richeditor-android' //This is the name you want to use for the published library. + version = '3.0.0pre0' -// repositories { -// maven { -// name = "GitHubPackages" -// url = uri("https://maven.pkg.github.com/niendo1/richeditor-android") -// credentials { -// username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") -// password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") -// } -// } -// } -// } -// } -// } -// } + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/niendo1/richeditor-android") + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") + } + } + } + } + } + } + } From 9d8feb9d074f71725f42ac5c987cc36c594888bb Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 20:20:46 +0100 Subject: [PATCH 085/136] prepare jitpack niendo1 --- build.gradle | 4 ---- gradle.properties | 2 +- richeditor/build.gradle | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 758842b..efb3bf0 100644 --- a/build.gradle +++ b/build.gradle @@ -10,10 +10,6 @@ buildscript { } } -plugins { - id 'maven-publish' -} - allprojects { repositories { google() diff --git a/gradle.properties b/gradle.properties index 10c22a1..831b602 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0pre0 +VERSION_NAME=3.0.0pre1 VERSION_CODE=290 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android diff --git a/richeditor/build.gradle b/richeditor/build.gradle index 6f4ee2c..da89cd8 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.android.library' + id 'maven-publish' } android { @@ -33,7 +34,7 @@ afterEvaluate { from components.release groupId = 'com.github.niendo1' //This should be the name of the publishing account artifactId = 'richeditor-android' //This is the name you want to use for the published library. - version = '3.0.0pre0' + version = '3.0.0pre1' repositories { maven { From 571f8e9ce6943ed9632c500295b2c56a324e618a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 20:37:31 +0100 Subject: [PATCH 086/136] prepare jitpack niendo1 --- build.gradle | 4 +++- jitpack.yml | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 jitpack.yml diff --git a/build.gradle b/build.gradle index efb3bf0..63c7300 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,9 @@ buildscript { classpath 'com.android.tools.build:gradle:8.2.0' } } - +plugins { + id 'maven-publish' +} allprojects { repositories { google() diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..faa03d2 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,4 @@ +jdk: + - openjdk11 +before_install: + - ./scripts/prepareJitpackEnvironment.sh From 9475065ccd16e6d877eea868043aeeced990654b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 20:55:04 +0100 Subject: [PATCH 087/136] prepare jitpack niendo1 --- jitpack.yml | 2 +- richeditor/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jitpack.yml b/jitpack.yml index faa03d2..f82bf6a 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk11 + - openjdk17 before_install: - ./scripts/prepareJitpackEnvironment.sh diff --git a/richeditor/build.gradle b/richeditor/build.gradle index da89cd8..d429ecf 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -34,7 +34,7 @@ afterEvaluate { from components.release groupId = 'com.github.niendo1' //This should be the name of the publishing account artifactId = 'richeditor-android' //This is the name you want to use for the published library. - version = '3.0.0pre1' + version = '3.0.0pre4' repositories { maven { From a72e502db830bcc521ba6d95a75a5d225f054dd0 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 21:00:18 +0100 Subject: [PATCH 088/136] prepare jitpack niendo1 --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index f82bf6a..f67f91c 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk17 + - jbr-17 before_install: - ./scripts/prepareJitpackEnvironment.sh From 0f8f60a8d8baf08cc87efd06462b4a0096ae77a8 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 21:18:43 +0100 Subject: [PATCH 089/136] prepare jitpack niendo1 --- build.gradle | 2 ++ jitpack.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 63c7300..758842b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,9 +9,11 @@ buildscript { classpath 'com.android.tools.build:gradle:8.2.0' } } + plugins { id 'maven-publish' } + allprojects { repositories { google() diff --git a/jitpack.yml b/jitpack.yml index f67f91c..3e3a8b6 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - jbr-17 + - jbr-21 before_install: - ./scripts/prepareJitpackEnvironment.sh From 83e11e2d451cdcff23674414243ca99233ff1d63 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 21:26:03 +0100 Subject: [PATCH 090/136] prepare jitpack niendo1 --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index 3e3a8b6..3928e84 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - jbr-21 + - openjdk21 before_install: - ./scripts/prepareJitpackEnvironment.sh From fcf71fe52fd254bd5c195c743971beb446b0a6e6 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 18 Dec 2023 21:37:54 +0100 Subject: [PATCH 091/136] prepare jitpack niendo1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 831b602..b776fed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects From d4ed6e7e7d7796703f8deb794f9f7a28c437ffb0 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 20:53:56 +0100 Subject: [PATCH 092/136] prepare jitpack niendo1 --- gradle.properties | 4 ++-- richeditor/build.gradle | 35 ++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/gradle.properties b/gradle.properties index b776fed..e69e0c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,11 +19,11 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0pre1 +VERSION_NAME=3.0.0pre6 VERSION_CODE=290 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android -#COMPILE_SDK_VERSION=34 +COMPILE_SDK_VERSION=34 TARGET_SDK_VERSION=33 MIN_SDK_VERSION=24 #android.defaults.buildfeatures.buildconfig=true diff --git a/richeditor/build.gradle b/richeditor/build.gradle index d429ecf..d158af3 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -4,20 +4,23 @@ plugins { } android { - compileSdk 34 + compileSdk COMPILE_SDK_VERSION as int defaultConfig { minSdkVersion MIN_SDK_VERSION as int targetSdkVersion TARGET_SDK_VERSION as int } namespace 'jp.wasabeef.richeditor' publishing { - singleVariant("release") + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } } buildTypes { release { debuggable false - minifyEnabled true + minifyEnabled false } } } @@ -27,15 +30,33 @@ dependencies { //testImplementation 'org.robolectric:robolectric:4.9.2' } + + +// WORKAROUND! If you comment this out gradle will report false duplicates +//task sourcesJar(type: Jar) { +// duplicatesStrategy = 'exclude' +// from subprojects.android.sourceSets.main.allSource +//} + +//task javadoc(type: Jar) { +// duplicatesStrategy = 'exclude' +// from subprojects.android.sourceSets.main.allSource +//} + +//java { +// withJavadocJar() +// withSourcesJar() +//} + afterEvaluate { publishing { publications { + release(MavenPublication) { - from components.release +// artifact sourcesJar // Publish the output of the sourceJar task groupId = 'com.github.niendo1' //This should be the name of the publishing account - artifactId = 'richeditor-android' //This is the name you want to use for the published library. - version = '3.0.0pre4' - + artifactId = ARTIFACT_ID as String //'richeditor-android' //This is the name you want to use for the published library. + version = VERSION_NAME as String repositories { maven { name = "GitHubPackages" From 1ec220109c5b299c7712e9acf2bb7654a60e24ce Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 21:38:03 +0100 Subject: [PATCH 093/136] prepare jitpack niendo1 --- richeditor/build.gradle | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/richeditor/build.gradle b/richeditor/build.gradle index d158af3..803dc5b 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -30,30 +30,12 @@ dependencies { //testImplementation 'org.robolectric:robolectric:4.9.2' } - - -// WORKAROUND! If you comment this out gradle will report false duplicates -//task sourcesJar(type: Jar) { -// duplicatesStrategy = 'exclude' -// from subprojects.android.sourceSets.main.allSource -//} - -//task javadoc(type: Jar) { -// duplicatesStrategy = 'exclude' -// from subprojects.android.sourceSets.main.allSource -//} - -//java { -// withJavadocJar() -// withSourcesJar() -//} - afterEvaluate { publishing { publications { - release(MavenPublication) { -// artifact sourcesJar // Publish the output of the sourceJar task + from components.release + //artifact sourcesJar // Publish the output of the sourceJar task groupId = 'com.github.niendo1' //This should be the name of the publishing account artifactId = ARTIFACT_ID as String //'richeditor-android' //This is the name you want to use for the published library. version = VERSION_NAME as String From 1f4403e060ddd337e8fc45c3908e987f8b468c75 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 21:55:21 +0100 Subject: [PATCH 094/136] prepare jitpack niendo1 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b33f706..f822a05 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,11 @@ Demo ![Demo](./art/demo2.gif) +Java Doc +--- + +[![javadoc](https://javadoc.io/badge2/org.springframework/spring-core/javadoc.svg)](https://javadoc.jitpack.io/com/github/niendo1/richeditor-android/latest/javadoc/) + How do I use it? --- @@ -104,6 +109,8 @@ dependencies { implementation 'com.github.jitpack:richeditor-android:3.0.0' } +[![Release](https://jitpack.io/v/niendo1/richeditor-android.svg)] (https://jitpack.io/#niendo1/richeditor-android) + ```groovy From 06301cfe41411186d9cc7b562d671156f7b4887b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 21:57:48 +0100 Subject: [PATCH 095/136] prepare jitpack niendo1 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f822a05..5354201 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ dependencies { implementation 'com.github.jitpack:richeditor-android:3.0.0' } + [![Release](https://jitpack.io/v/niendo1/richeditor-android.svg)] (https://jitpack.io/#niendo1/richeditor-android) ```groovy From c613a37564e5a4000b6166132e6b8f16326a6e67 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:21:12 +0100 Subject: [PATCH 096/136] prepare jitpack niendo1 --- README.md | 27 +++++++++++++-------------- art/javadoc.svg | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 art/javadoc.svg diff --git a/README.md b/README.md index 5354201..e02f017 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,24 @@ -

+

-

+

- - + - - - + + + +

-This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) +~~This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) `RichEditor for Android` is a beautiful Rich Text `WYSIWYG Editor` for `Android`. @@ -88,11 +91,6 @@ Demo ![Demo](./art/demo2.gif) -Java Doc ---- - -[![javadoc](https://javadoc.io/badge2/org.springframework/spring-core/javadoc.svg)](https://javadoc.jitpack.io/com/github/niendo1/richeditor-android/latest/javadoc/) - How do I use it? --- @@ -110,7 +108,8 @@ dependencies { } -[![Release](https://jitpack.io/v/niendo1/richeditor-android.svg)] (https://jitpack.io/#niendo1/richeditor-android) + + ```groovy diff --git a/art/javadoc.svg b/art/javadoc.svg new file mode 100644 index 0000000..e45fc64 --- /dev/null +++ b/art/javadoc.svg @@ -0,0 +1 @@ +javadoc: 6.1.2javadoc6.1.2 From d79acf3e298c0ecedef63c3d7e4c44835ddd8ef1 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:24:40 +0100 Subject: [PATCH 097/136] prepare jitpack niendo1 --- README.md | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index e02f017..7ae7a88 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,16 @@

- +

- - - - - - - - - + + + + + + +

~~This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) @@ -107,10 +102,6 @@ dependencies { implementation 'com.github.jitpack:richeditor-android:3.0.0' } - - - - ```groovy From b79c937cdd6f99abcf43ae6421b5d26c0e2c0dc5 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:25:40 +0100 Subject: [PATCH 098/136] prepare jitpack niendo1 --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 7ae7a88..5e6edb6 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,9 @@

- - + - -

From 5ab9368f580042957f0e49db9f3a768c113dd7a9 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:26:26 +0100 Subject: [PATCH 099/136] prepare jitpack niendo1 --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5e6edb6..ef2f53a 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@

-

- - - - +

+ + + +

~~This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) From 4559458f3f460eba9e3bc3a0c41a0a3deaf805a8 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:27:27 +0100 Subject: [PATCH 100/136] prepare jitpack niendo1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ef2f53a..1f84944 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -

+

-

+

From 59d427d60552532c3b7c56ee5145b45d1df948f6 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:28:57 +0100 Subject: [PATCH 101/136] prepare jitpack niendo1 --- README.md | 4 ++-- art/javadoc.svg | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1f84944..d495a9c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -

+

-

+

diff --git a/art/javadoc.svg b/art/javadoc.svg index e45fc64..eafab31 100644 --- a/art/javadoc.svg +++ b/art/javadoc.svg @@ -1 +1 @@ -javadoc: 6.1.2javadoc6.1.2 +javadoc: 6.1.2javadoc3.0.0 From 6d8f1bc8c8a88627369eec04cdbc6a6c6bd22901 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 19 Dec 2023 23:32:31 +0100 Subject: [PATCH 102/136] prepare jitpack niendo1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e69e0c1..e3eb06d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0pre6 +VERSION_NAME=3.0.0pre9 VERSION_CODE=290 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android From ed972e786700fb83a4647b62883c6204670537af Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 20 Dec 2023 22:38:55 +0100 Subject: [PATCH 103/136] add some javadoc niendo1 --- README.md | 25 +- .../jp/wasabeef/richeditor/RichEditor.java | 398 +++++++++++++++++- .../java/jp/wasabeef/richeditor/Utils.java | 21 + 3 files changed, 421 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index d495a9c..a113422 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@

- - - + Logo

-

- - - - +

Android Arsenal +License Apache 2.0 +JitPack-Lib +JavaDoc

-~~This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) +--- + +This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorView](https://github.com/Andrew-Chen-Wang/RichEditorView) + +--- `RichEditor for Android` is a beautiful Rich Text `WYSIWYG Editor` for `Android`. @@ -90,6 +91,7 @@ How do I use it? ##### Gradle +```groovy repositories { mavenCentral() maven { url "https://jitpack.io" } @@ -98,11 +100,8 @@ repositories { dependencies { implementation 'com.github.jitpack:richeditor-android:3.0.0' } - -```groovy - - ``` + ### Default Setting for Editor --- diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 1588f7c..b7853d5 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -48,32 +48,74 @@ * limitations under the License. */ +/** + * This class provides the HTML-Editor. + * + */ public class RichEditor extends WebView implements ValueCallback { + /** + * + */ public enum Type { BOLD, ITALIC, SUBSCRIPT, SUPERSCRIPT, STRIKETHROUGH, UNDERLINE, H1, H2, H3, H4, H5, H6, HTML, HR, ORDEREDLIST, UNORDEREDLIST, JUSTIFYCENTER, JUSTIFYFULL, JUSTIFYLEFT, JUSTIFYRIGHT } private final AtomicBoolean mEvaluateFinished = new AtomicBoolean(false); + /** + * Callback interface to receive data from the editor + * + * Example code + *
+   *    mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() {
+   *       @Override
+   *       public void onTextChange(String text) {
+   *         mEditor.setOnJSDataListener(value -> {
+   *
+   *           // do something with value
+   *
+   *         });
+   *         mEditor.getHtml();
+   *       }
+   *     });
+   * 
+ */ public interface onJSDataListener { public void onDataReceived(String value); - //public void onActionFailure(Throwable throwableError); } + /** + * The class implements this listener to receive notifications when clicks occure + * in the html editor + * @todo + */ public interface onClickListener { public void onClick(String value); - //public void onActionFailure(Throwable throwableError); } + /** + * The class implements this listener to receive notifications when clicks occur + * in the html editor + * @see onJSDataListener + * @todo + */ public interface OnTextChangeListener { void onTextChange(String text); } + /** + * The class implements this listener to receive notifications when state changes occur + * in the html editor + * @todo + */ public interface OnDecorationStateListener { void onStateChangeListener(String text, List types); } + /** + * The class implements this listener to receive notifications the html editor is ready initialised + */ public interface AfterInitialLoadListener { void onAfterInitialLoad(boolean isReady); } @@ -89,14 +131,29 @@ public interface AfterInitialLoadListener { private OnDecorationStateListener mDecorationStateListener; private AfterInitialLoadListener mLoadListener; + /** + * Constructs a new RichEditor with an Activity Context object. + * @param context + */ public RichEditor(Context context) { this(context, null); } + /** + * Constructs a new RichEditor with layout parameters. + * @param context + * @param attrs + */ public RichEditor(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.webViewStyle); } + /** + * Constructs a new RichEditor with layout parameters and a default style + * @param context + * @param attrs + * @param defStyleAttr + */ @SuppressLint("SetJavaScriptEnabled") public RichEditor(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @@ -115,14 +172,27 @@ protected EditorWebViewClient createWebviewClient() { return new EditorWebViewClient(); } + /** + * Register a callback to be invoked when the html text is changed + * @param listener The callback that will run This value may be null. + */ public void setOnTextChangeListener(OnTextChangeListener listener) { mTextChangeListener = listener; } + /** + * Register a callback to be invoked when the editor is clicked + * @param listener The callback that will run This value may be null. + */ public void setOnClickListener(onClickListener listener) { mClickListener = listener; } + /** + * Register a callback to be invoked when data needs to be transferred from the editor to the main program + * @see onJSDataListener + * @param listener The callback that will run This value may be null. + */ public void setOnJSDataListener(onJSDataListener listener) { mJSDataListener = listener; } @@ -131,10 +201,18 @@ public void setOnDecorationChangeListener(OnDecorationStateListener listener) { mDecorationStateListener = listener; } + /** + * Register a callback to be invoked when the editor finished loading and is ready to use + * @param listener The callback that will run This value may be null. + */ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { mLoadListener = listener; } + /** + * Value callback + * @param value The value. + */ @Override public void onReceiveValue(String value) { String unescaped= null; @@ -218,6 +296,15 @@ private void applyAttributes(Context context, AttributeSet attrs) { ta.recycle(); } + /** + * Load html text in the the editor. + *
+   *   SetupRichEditor();
+   *   String HtmlText = "

Header 1

" + * editText.setHtml(HtmlText); + *
+ * @param contents string with html content + */ public void setHtml(String contents) { if (contents == null) { contents = ""; @@ -229,28 +316,59 @@ public void setHtml(String contents) { } } + /** + * Requests the complete html data from the editor. Data comes via callback + * @see onJSDataListener() + *
+   *         mEditor.setOnJSDataListener(value -> {
+   *             do something with value
+   *         });
+   *         mEditor.getHtml();
+   * 
+ * @return the html content of the editor + */ public String getHtml() { requestJSData("RE.getHtml()"); return("data can only received by callback"); } - /// Text representation of the data that has been input into the editor view, if it has been loaded. + /** + * Text representation of the data that has been input into the editor view, if it has been loaded. + * Data comes via callback. + * @see #getHtml + * @return the text + */ public boolean getText() { return requestJSData("RE.getText()"); } - /// Returns selected text + /** + * Returns selected text + * Data comes via callback. + * @see #getHtml + * @return the selected text + */ public boolean getSelectedText() { return requestJSData("RE.selectedText()"); } - /// Returns HTML-Code from selected range + /** + * Returns HTML-Code from selected range + * Data comes via callback. + * @see #getHtml + * @return HTML-Code + */ public boolean getSelectedHtml() { return requestJSData("RE.selectedHtml()"); } - /// The href of the current selection, if the current selection's parent is an anchor tag. - /// Will be nil if there is no href, or it is an empty string. + /** + * The href of the current selection, if the current selection's parent is an anchor tag. + * Will be nil if there is no href, or it is an empty string. + * Data comes via callback. + * @see #getHtml + * @return false - if no selection + */ public boolean getSelectedHref() { if (!hasRangeSelection()) { return false; @@ -259,25 +377,53 @@ public boolean getSelectedHref() { } } - /// Whether or not the selection has a type specifically of "Range". + /** + * Whether or not the selection has a type specifically of "Range". + * Data comes via callback. + * @see #getHtml + * @return + */ public boolean hasRangeSelection() { return requestJSData("RE.rangeSelectionExists()"); } - /// Whether or not the selection has a type specifically of "Range" or "Caret". + /** + * Whether or not the selection has a type specifically of "Range" or "Caret". + * Data comes via callback. + * @see #getHtml + * @return + */ public boolean hasRangeOrCaretSelection() { return requestJSData("RE.rangeOrCaretSelectionExists()"); } + /** + * Sets the font color of the editor + *
+   *   mEditor.setEditorFontColor(getColor(R.color.EditorTxtColor));
+   * 
+ * @param color + */ public void setEditorFontColor(int color) { String hex = convertHexColorString(color); exec("javascript:RE.setBaseTextColor('" + hex + "');"); } + /** + * Sets the font size in pixels + * @param px font size + */ public void setEditorFontSize(int px) { exec("javascript:RE.setBaseFontSize('" + px + "px');"); } + /** + * sets the padding + * @param left the left padding in pixels + * @param top the top padding in pixels + * @param right the right padding in pixels + * @param bottom the bottom padding in pixels + */ @Override public void setPadding(int left, int top, int right, int bottom) { super.setPadding(left, top, right, bottom); @@ -285,21 +431,44 @@ public void setPadding(int left, int top, int right, int bottom) { + "px');"); } + /** + * sets the relative padding + * @todo same as @see #setPadding() + * @param start the start padding in pixels + * @param top the top padding in pixels + * @param end the end padding in pixels + * @param bottom the bottom padding in pixels + */ @Override public void setPaddingRelative(int start, int top, int end, int bottom) { // still not support RTL. setPadding(start, top, end, bottom); } + /** + * Sets the back color of the editor + * @param color the color of the background + */ public void setEditorBackgroundColor(int color) { setBackgroundColor(color); } + /** + * Sets the back color of the editor + * @param color the color of the background + */ @Override public void setBackgroundColor(int color) { super.setBackgroundColor(color); } + /** + * set a background resource + *
+   *   mEditor.setBackgroundResource(R.drawable.bg);
+   * 
+ * @param resid The identifier of the resource. + */ @Override public void setBackgroundResource(int resid) { Bitmap bitmap = Utils.decodeResource(getContext(), resid); @@ -309,6 +478,11 @@ public void setBackgroundResource(int resid) { exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');"); } + /** + * The Drawable (png) to use as the background, or null to remove the background + * @param background The Drawable to use as the background, or null to remove the + * background + */ @Override public void setBackground(Drawable background) { Bitmap bitmap = Utils.toBitmap(background); @@ -318,26 +492,49 @@ public void setBackground(Drawable background) { exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');"); } + /** + * The URL (png) to use as the background + *
+   *   mEditor.setBackground("https://raw.githubusercontent.com/wasabeef/art/master/chip.png");
+   * 
+ * @param url The Drawable to use as the background, or null to remove the + * background + */ public void setBackground(String url) { exec("javascript:RE.setBackgroundImage('url(" + url + ")');"); } + /** + * @param px + */ public void setEditorWidth(int px) { exec("javascript:RE.setWidth('" + px + "px');"); } + /** + * @param px + */ public void setEditorHeight(int px) { exec("javascript:RE.setHeight('" + px + "px');"); } + /** + * @param placeholder + */ public void setPlaceholder(String placeholder) { exec("javascript:RE.setPlaceholderText('" + placeholder + "');"); } + /** + * @param inputEnabled + */ public void setInputEnabled(Boolean inputEnabled) { exec("javascript:RE.setInputEnabled(" + inputEnabled + ")"); } + /** + * @param cssFile + */ public void loadCSS(String cssFile) { String jsCSSImport = "(function() {" + " var head = document.getElementsByTagName(\"head\")[0];" @@ -347,89 +544,153 @@ public void loadCSS(String cssFile) { exec("javascript:" + jsCSSImport + ""); } + /** + * + */ public void undo() { exec("javascript:RE.undo();"); } + /** + * + */ public void redo() { exec("javascript:RE.redo();"); } + /** + * + */ public void setPre() { exec("javascript:RE.setPre();"); } + /** + * + */ public void toggleBold() { exec("javascript:RE.toggleBold();"); } + /** + * + */ public void setBold(boolean enabled) { exec("javascript:RE.setBold(" + enabled + ");"); } + /** + * + */ public void toggleItalic() { exec("javascript:RE.toggleItalic();"); } + /** + * + */ public void setItalic(boolean enabled) { exec("javascript:RE.setItalic(" + enabled + ");"); } + /** + * + */ public void setSubscript() { exec("javascript:RE.setSubscript();"); } + /** + * + */ public void setSuperscript() { exec("javascript:RE.setSuperscript();"); } + /** + * + */ public void toggleStrikeThrough() { exec("javascript:RE.toggleStrikeThrough();"); } + /** + * @param enabled + */ public void setStrikeThrough(boolean enabled) { exec("javascript:RE.setStrikeThrough(" + enabled + ");"); } + /** + * + */ public void toggleUnderline() { exec("javascript:RE.toggleUnderline();"); } + /** + * @param enabled + */ public void setUnderline(boolean enabled) { exec("javascript:RE.setUnderline(" + enabled + ");"); } + /** + * @param color + */ public void setTextColor(int color) { setTextColor(convertHexColorString(color)); } + /** + * @param color + */ public void setTextColor(String color) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextColor('" + color + "');"); } + /** + * @param color + */ public void setTextBackgroundColor(int color) { setTextBackgroundColor(convertHexColorString(color)); } + /** + * @param color + */ public void setTextBackgroundColor(String color) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextBackgroundColor('" + color + "');"); } + /** + * @param fontFamily + */ public void setFontFamily(String fontFamily) { exec("javascript:RE.setFontFamily('" + fontFamily + "');"); } + /** + * @param name + * @param url + */ public void LoadFont(String name, String url) { exec("javascript:RE.LoadFont('" + name + "','"+url+"');"); } + /** + * + */ public void getFontFamily() { requestJSData("javascript:RE.getFontFamily();"); } + /** + * @param fontSize + */ public void setFontSize(int fontSize) { if (fontSize > 7 || fontSize < 1) { Log.e("RichEditor", "Font size should have a value between 1-7"); @@ -437,44 +698,85 @@ public void setFontSize(int fontSize) { exec("javascript:RE.setFontSize('" + fontSize + "');"); } + /** + * + */ public void removeFormat() { exec("javascript:RE.removeFormat();"); } + /** + * @param heading + */ public void setHeading(int heading) { exec("javascript:RE.setHeading('" + heading + "');"); } + /** + * + */ public void setIndent() { exec("javascript:RE.setIndent();"); } + /** + * + */ public void setOutdent() { exec("javascript:RE.setOutdent();"); } + /** + * + */ public void setAlignLeft() { exec("javascript:RE.setJustifyLeft();"); } + /** + * + */ public void setAlignCenter() { exec("javascript:RE.setJustifyCenter();"); } + /** + * + */ public void setAlignRight() { exec("javascript:RE.setJustifyRight();"); } + /** + * + */ public void setBlockquote() { exec("javascript:RE.setBlockquote();"); } + /** + * + */ public void setBullets() { setUnorderedList(); } + + /** + * + */ public void setUnorderedList() { exec("javascript:RE.setUnorderedList();"); } + /** + * + */ public void setNumbers() { setOrderedList(); } + + /** + * + */ public void setOrderedList() { exec("javascript:RE.setOrderedList();"); } + /** + * @param text + */ public void insertHTML(String text) { exec("javascript:RE.prepareInsert();"); text = text.replace("\n", "
") @@ -483,11 +785,18 @@ public void insertHTML(String text) { exec("javascript:RE.insertHTML('" + text + "');"); } + /** + * + */ public void insertHR_Line() { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertHTML('
');"); } + /** + * @param section + * @param content + */ public void insertCollapsibleSection(String section, String content) { exec("javascript:RE.insertCollapsibleSection('"+section+"', '"+content+"');"); } @@ -555,46 +864,79 @@ public void insertVideo(String url, String alt, String width, String height) { exec("javascript:RE.insertVideo('" + url + "', '" + alt + "', '" + width + "' '" + height + "');"); } + /** + * @param url + */ public void insertAudio(String url) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertAudio('" + url + "');"); } + /** + * @param url + */ public void insertYoutubeVideo(String url) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertYoutubeVideo('" + url + "');"); } + /** + * @param url + * @param width + */ public void insertYoutubeVideo(String url, int width) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "');"); } + /** + * @param url + * @param width + * @param height + */ public void insertYoutubeVideo(String url, int width, int height) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "', '" + height + "');"); } + /** + * @param href + * @param text + * @param title + */ public void insertLink(String href, String text, String title) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertLink('" + href + "', '" + text + "', '" + title + "');"); } + /** + * + */ public void insertCheckbox() { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setCheckbox();"); } + /** + * + */ public void focusEditor() { requestFocus(); exec("javascript:RE.focus();"); } + /** + * @param x + * @param y + */ public void focus(Integer x, Integer y) { requestFocus(); exec("javascript:RE.focusAtPoint("+ x.toString() + ", "+ y.toString() + ")"); } + /** + * + */ public void clearFocusEditor() { exec("javascript:RE.blurFocus();"); } @@ -615,29 +957,48 @@ protected void exec(final String trigger) { } } + /** + * @param col + * @param row + */ // MARK: Table functionalities public void insertTable(Integer col, Integer row) { exec("javascript:RE.prepareInsert()"); exec("javascript:RE.insertTable("+ col.toString() + "," + row.toString() + ")"); } - /// Checks if cursor is in a table element. If so, return true so that you can add menu items accordingly. + /** + * Checks if cursor is in a table element. If so, return true so that you can add menu items accordingly. + * + */ public void isCursorInTable() { requestJSData("javascript:RE.isCursorInTable"); } + /** + * + */ public void addRowToTable() { exec("javascript:RE.addRowToTable()"); } + /** + * + */ public void deleteRowFromTable() { exec("javascript:RE.deleteRowFromTable()"); } + /** + * + */ public void addColumnToTable() { exec("javascript:RE.addColumnToTable()"); } + /** + * + */ public void deleteColumnFromTable() { exec("javascript:RE.deleteColumnFromTable()"); } @@ -650,6 +1011,10 @@ private void load(String trigger) { } } + /** + * @param cmdJS + * @return + */ public boolean requestJSData(String cmdJS) { // https://stackoverflow.com/questions/38380246/espresso-how-to-call-evaluatejavascript-on-a-webview mEvaluateFinished.set(false); @@ -658,6 +1023,9 @@ public boolean requestJSData(String cmdJS) { return true; } + /** + * + */ protected class EditorWebViewClient extends WebViewClient { @Override public void onPageFinished(WebView view, String url) { @@ -667,6 +1035,11 @@ public void onPageFinished(WebView view, String url) { } } + /** + * @param view The WebView that is initiating the callback. + * @param url The URL to be loaded. + * @return + */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { String decode = Uri.decode(url); @@ -682,6 +1055,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return super.shouldOverrideUrlLoading(view, url); } + /** + * @param view The WebView that is initiating the callback. + * @param request Object containing the details of the request. + * @return + */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java index 6286a4d..8cc5a84 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/Utils.java @@ -26,12 +26,24 @@ * limitations under the License. */ +/** + * This class provides some converting functions. + * + */ public final class Utils { + /** + * @throws InstantiationException + */ private Utils() throws InstantiationException { throw new InstantiationException("This class is not for instantiation"); } + /** + * @param bitmap + * @param type + * @return + */ public static String toBase64(Bitmap bitmap, String type) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (type.contains("jpg") || type.contains("jpeg")) @@ -44,6 +56,10 @@ else if (type.contains("webp")) return Base64.encodeToString(baos.toByteArray(), Base64.NO_WRAP); } + /** + * @param drawable + * @return + */ public static Bitmap toBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); @@ -62,6 +78,11 @@ public static Bitmap toBitmap(Drawable drawable) { return bitmap; } + /** + * @param context + * @param resId + * @return + */ public static Bitmap decodeResource(Context context, int resId) { return BitmapFactory.decodeResource(context.getResources(), resId); } From 21c5c2f86f5bf6b61de9561290c93fb9fd823450 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 28 Dec 2023 23:13:08 +0100 Subject: [PATCH 104/136] README fixes niendo1 --- README.md | 10 ++++++---- richeditor/build.gradle | 3 +-- richeditor/src/main/java/overview.html | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 richeditor/src/main/java/overview.html diff --git a/README.md b/README.md index a113422..1c2e192 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -

- Logo +

+ Logo

-

Android Arsenal +

+Android Arsenal License Apache 2.0 JitPack-Lib JavaDoc @@ -13,7 +14,7 @@ This is a fork, which tries to merge changes from [Andrew-Chen-Wang/RichEditorVi --- -`RichEditor for Android` is a beautiful Rich Text `WYSIWYG Editor` for `Android`. +`RichEditor for Android` is a beautiful HTML `WYSIWYG Editor` for `Android` based on webview. - _Looking for iOS? Check out_ [cjwirth/RichEditorView](https://github.com/cjwirth/RichEditorView) @@ -49,6 +50,7 @@ Supported Functions - [x] Insert Image - [x] (new) Insert Inline Image - [x] Insert Youtube +- [x] Insert iframe (new) - [x] Insert Video - [x] Insert Audio - [x] Insert Link diff --git a/richeditor/build.gradle b/richeditor/build.gradle index 803dc5b..6709ac6 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -26,7 +26,7 @@ android { } dependencies { - //testImplementation 'junit:junit:4.13.2' + testImplementation 'junit:junit:4.13.2' //testImplementation 'org.robolectric:robolectric:4.9.2' } @@ -35,7 +35,6 @@ afterEvaluate { publications { release(MavenPublication) { from components.release - //artifact sourcesJar // Publish the output of the sourceJar task groupId = 'com.github.niendo1' //This should be the name of the publishing account artifactId = ARTIFACT_ID as String //'richeditor-android' //This is the name you want to use for the published library. version = VERSION_NAME as String diff --git a/richeditor/src/main/java/overview.html b/richeditor/src/main/java/overview.html new file mode 100644 index 0000000..3a614e1 --- /dev/null +++ b/richeditor/src/main/java/overview.html @@ -0,0 +1,21 @@ + + + + API Overview + + +

+ RichEditor for Android is a beautiful Rich Text WYSIWYG Editor for Android. +

+

+ The library is available as JitPack. +

+

+ The latest JavaDoc pages can be found on jitpack.ioa> as well. +

+

+ Short overview of the API. +

+ + + From a3d5d3c057ec28a35af2084831f358da58cf7b31 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 28 Dec 2023 23:16:43 +0100 Subject: [PATCH 105/136] javadoc changes niendo1 --- .../jp/wasabeef/richeditor/RichEditor.java | 213 ++++++++++++------ 1 file changed, 142 insertions(+), 71 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index b7853d5..5d20cd9 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -86,7 +86,7 @@ public interface onJSDataListener { } /** - * The class implements this listener to receive notifications when clicks occure + * The class implements this listener to receive notifications when clicks occur * in the html editor * @todo */ @@ -167,7 +167,11 @@ public RichEditor(Context context, AttributeSet attrs, int defStyleAttr) { applyAttributes(context, attrs); } - + /** + * Creates and returns an instance of the protected inner class EditorWebViewClient. + * + * @return An instance of the EditorWebViewClient class. + */ protected EditorWebViewClient createWebviewClient() { return new EditorWebViewClient(); } @@ -316,6 +320,28 @@ public void setHtml(String contents) { } } + /** + * Requests JavaScript data from the WebView by executing the specified JavaScript command. + * This method uses the evaluateJavascript method to execute the provided JavaScript command + * and waits for the evaluation to finish before returning. + * + * @param cmdJS The JavaScript command to be executed in the WebView. + * @return true if the JavaScript command was successfully requested, false otherwise. + * + * @see + * Stack Overflow: Espresso - How to call evaluateJavascript on a WebView + */ + public boolean requestJSData(String cmdJS) { + // https://stackoverflow.com/questions/38380246/espresso-how-to-call-evaluatejavascript-on-a-webview + mEvaluateFinished.set(false); + + // Execute the specified JavaScript command and set the evaluation flag + evaluateJavascript(cmdJS, this); + + // Return true to indicate that the JavaScript command was successfully requested + return true; + } + /** * Requests the complete html data from the editor. Data comes via callback * @see onJSDataListener() @@ -505,34 +531,42 @@ public void setBackground(String url) { } /** - * @param px + * Sets width of the editor in pixels + * @param px new width */ public void setEditorWidth(int px) { exec("javascript:RE.setWidth('" + px + "px');"); } /** - * @param px + * Sets height of the editor in pixels + * @param px new height */ public void setEditorHeight(int px) { exec("javascript:RE.setHeight('" + px + "px');"); } /** - * @param placeholder + * Sets a hint in the empty editor + *
+   *   mEditor.setPlaceholder("Insert text here...");
+   * 
+ * @param placeholder the text */ public void setPlaceholder(String placeholder) { exec("javascript:RE.setPlaceholderText('" + placeholder + "');"); } /** - * @param inputEnabled + * Make the editor writable + * @param inputEnabled true=writable, false=read only */ public void setInputEnabled(Boolean inputEnabled) { exec("javascript:RE.setInputEnabled(" + inputEnabled + ")"); } /** + * Loads an additional CSS file * @param cssFile */ public void loadCSS(String cssFile) { @@ -545,76 +579,77 @@ public void loadCSS(String cssFile) { } /** - * + * reverts the last action */ public void undo() { exec("javascript:RE.undo();"); } /** - * + * reverts the last revert action */ public void redo() { exec("javascript:RE.redo();"); } /** - * + * set html tag
 
*/ public void setPre() { exec("javascript:RE.setPre();"); } /** - * + * toggle font attribute bold */ public void toggleBold() { exec("javascript:RE.toggleBold();"); } /** - * + * set font attribute bold */ public void setBold(boolean enabled) { exec("javascript:RE.setBold(" + enabled + ");"); } /** - * + * toggle font attribute Italic */ public void toggleItalic() { exec("javascript:RE.toggleItalic();"); } /** - * + * set font attribute Italic */ public void setItalic(boolean enabled) { exec("javascript:RE.setItalic(" + enabled + ");"); } /** - * + * set font attribute Sub script */ public void setSubscript() { exec("javascript:RE.setSubscript();"); } /** - * + * set font attribute super script */ public void setSuperscript() { exec("javascript:RE.setSuperscript();"); } /** - * + * toggle font attribute Strike Through */ public void toggleStrikeThrough() { exec("javascript:RE.toggleStrikeThrough();"); } /** + * set font attribute Strike Through * @param enabled */ public void setStrikeThrough(boolean enabled) { @@ -622,13 +657,14 @@ public void setStrikeThrough(boolean enabled) { } /** - * + * toggle font attribute Under line */ public void toggleUnderline() { exec("javascript:RE.toggleUnderline();"); } /** + * set font attribute Under line * @param enabled */ public void setUnderline(boolean enabled) { @@ -636,6 +672,7 @@ public void setUnderline(boolean enabled) { } /** + * set text color by value * @param color */ public void setTextColor(int color) { @@ -643,6 +680,10 @@ public void setTextColor(int color) { } /** + * set text color by string + *
+   *   mEditor.setTextColor("red")
+   * 
* @param color */ public void setTextColor(String color) { @@ -651,6 +692,7 @@ public void setTextColor(String color) { } /** + * Sets Background color for text by number * @param color */ public void setTextBackgroundColor(int color) { @@ -659,7 +701,11 @@ public void setTextBackgroundColor(int color) { } /** - * @param color + * Sets Background color for text by string + *
+   * mEditor.setTextColor("red")
+   * 
+ * @param color as string */ public void setTextBackgroundColor(String color) { exec("javascript:RE.prepareInsert();"); @@ -667,6 +713,9 @@ public void setTextBackgroundColor(String color) { } /** + * set the font family + * @see #getFontFamily for a list of available font families + * @see #LoadFont to add new fonts * @param fontFamily */ public void setFontFamily(String fontFamily) { @@ -674,7 +723,9 @@ public void setFontFamily(String fontFamily) { } /** - * @param name + * loads a new font file (for example ttf) + * @see #setFontFamily to access this font + * @param name to access this font * @param url */ public void LoadFont(String name, String url) { @@ -682,14 +733,16 @@ public void LoadFont(String name, String url) { } /** - * + * gets a list of available fonts/font families + * @see #setFontFamily to access one of these fonts/font families */ public void getFontFamily() { requestJSData("javascript:RE.getFontFamily();"); } /** - * @param fontSize + * sets the font size + * @param fontSize in steps 1 tru 7 */ public void setFontSize(int fontSize) { if (fontSize > 7 || fontSize < 1) { @@ -699,73 +752,81 @@ public void setFontSize(int fontSize) { } /** - * + * removes all the formats for the actual selection */ public void removeFormat() { exec("javascript:RE.removeFormat();"); } /** - * @param heading + * Sets the selected text or cursor position to a specific heading level in the Rich Editor WebView. + * + * @param heading The heading level to set, where 1 is the highest (largest) heading and + * larger values represent lower (smaller) headings. */ public void setHeading(int heading) { exec("javascript:RE.setHeading('" + heading + "');"); } /** - * + * Shifts the actual text selection or cursor position to the right in the Rich Editor WebView. + * This is used to create an indentation effect. */ public void setIndent() { exec("javascript:RE.setIndent();"); } /** - * + * Shifts the actual text selection or cursor position to the left in the Rich Editor WebView. + * This is used to remove indentation. */ public void setOutdent() { exec("javascript:RE.setOutdent();"); } /** - * + * Aligns the selected text or cursor position to the left in the Rich Editor WebView. */ public void setAlignLeft() { exec("javascript:RE.setJustifyLeft();"); } /** - * + * Aligns the selected text or cursor position to the center in the Rich Editor WebView. */ public void setAlignCenter() { exec("javascript:RE.setJustifyCenter();"); } /** - * + * Aligns the selected text or cursor position to the right in the Rich Editor WebView. */ public void setAlignRight() { exec("javascript:RE.setJustifyRight();"); } /** - * + * Applies blockquote styling to the selected text or cursor position in the Rich Editor WebView. + * This is used to create a blockquote effect. */ public void setBlockquote() { exec("javascript:RE.setBlockquote();"); } /** - * + * Sets the selected text or cursor position to use bullets in the Rich Editor WebView. + * This method is an alias for {@link #setUnorderedList()}. */ public void setBullets() { setUnorderedList(); } /** - * + * Sets the selected text or cursor position to use an unordered list (bullets) in the Rich Editor WebView. */ public void setUnorderedList() { exec("javascript:RE.setUnorderedList();"); } /** - * + * Sets the selected text or cursor position to use numbers in the Rich Editor WebView. + * This method is an alias for {@link #setOrderedList()}. */ public void setNumbers() { setOrderedList(); } @@ -775,6 +836,7 @@ public void setBlockquote() { public void setOrderedList() { exec("javascript:RE.setOrderedList();"); } /** + * Insert a HTML string into the Rich Editor WebView. * @param text */ public void insertHTML(String text) { @@ -786,7 +848,8 @@ public void insertHTML(String text) { } /** - * + * Inserts a horizontal rule (line) into the Rich Editor WebView. + * This method prepares the editor for insertion and then adds an HTML horizontal rule. */ public void insertHR_Line() { exec("javascript:RE.prepareInsert();"); @@ -794,19 +857,21 @@ public void insertHR_Line() { } /** - * @param section - * @param content + * Inserts a collapsible section into the Rich Editor WebView. + * + * @param section The title or label for the collapsible section. + * @param content The content to be included in the collapsible section. */ public void insertCollapsibleSection(String section, String content) { exec("javascript:RE.insertCollapsibleSection('"+section+"', '"+content+"');"); } /** - * {@link RichEditor#insertImage(String, String, String, String, Boolean)} will show the original size of the image. + * Inserts an image into the Rich Editor as link * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. * - * @param url - * @param alt + * @param url The URI of the image to be inserted. + * @param alt The alternative text for the image. * @param width Width of the Image; if relative=true then 100 means 100% page width * @param height Height of the Image * @param relative Image size is relative to page width @@ -817,15 +882,15 @@ public void insertImage(String url, String alt, String width, String height, Boo } /** - * {@link RichEditor#insertImageAsBase64(Uri, String, String, String, Boolean, Integer)} will show the original size of the image. - * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. + * Inserts an image into the Rich Editor WebView using Base64 encoding from the provided image URI. + * This method allows manual processing of the image, adjusting width and height to fit different mobile screens. * - * @param imageURI - * @param alt - * @param width Width of the Image; if relative=true then 100 means 100% page width - * @param height Height of the Image - * @param relative Image size is relative to page width - * @param inSampleSize Shrink Image size + * @param imageURI The URI of the image to be inserted. + * @param alt The alternative text for the image. + * @param width The width of the image; if relative is true, 100 means 100% page width. + * @param height The height of the image. + * @param relative Indicates if the image size is relative to the page width. + * @param inSampleSize Shrink the image size. */ public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative, Integer inSampleSize) { InputStream inputStream = null; @@ -851,7 +916,7 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h } /** - * {@link RichEditor#insertVideo(String, String, String, String)} will show the original size of the video. + * Will show the original size of the video. * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. * * @param url @@ -865,7 +930,10 @@ public void insertVideo(String url, String alt, String width, String height) { } /** - * @param url + * Inserts an audio element into the Rich Editor WebView at the current cursor position or selection. + * + * @param url The URL of the audio file to be inserted. + * @param optProperties additional properties like 'autoplay, loop' */ public void insertAudio(String url) { exec("javascript:RE.prepareInsert();"); @@ -910,7 +978,7 @@ public void insertLink(String href, String text, String title) { } /** - * + * Inserts a check box */ public void insertCheckbox() { exec("javascript:RE.prepareInsert();"); @@ -918,7 +986,7 @@ public void insertCheckbox() { } /** - * + * Set focus */ public void focusEditor() { requestFocus(); @@ -926,6 +994,7 @@ public void focusEditor() { } /** + * Set focus on point * @param x * @param y */ @@ -935,7 +1004,7 @@ public void focus(Integer x, Integer y) { } /** - * + * Clears the focus and blurs the editor */ public void clearFocusEditor() { exec("javascript:RE.blurFocus();"); @@ -958,10 +1027,12 @@ protected void exec(final String trigger) { } /** - * @param col - * @param row + * Inserts a table with the specified number of columns and rows into the Rich Editor WebView. + * This method executes JavaScript commands to prepare for table insertion and insert the table. + * + * @param col The number of columns in the table. + * @param row The number of rows in the table. */ - // MARK: Table functionalities public void insertTable(Integer col, Integer row) { exec("javascript:RE.prepareInsert()"); exec("javascript:RE.insertTable("+ col.toString() + "," + row.toString() + ")"); @@ -976,28 +1047,32 @@ public void isCursorInTable() { } /** - * + * Adds a new row to the table in the Rich Editor WebView. + * This method executes a JavaScript command to add a new row to the table. */ public void addRowToTable() { exec("javascript:RE.addRowToTable()"); } /** - * + * Deletes the currently selected row from the table in the Rich Editor WebView. + * This method executes a JavaScript command to delete the currently selected row from the table. */ public void deleteRowFromTable() { exec("javascript:RE.deleteRowFromTable()"); } /** - * + * Adds a new column to the table in the Rich Editor WebView. + * This method executes a JavaScript command to add a new column to the table. */ public void addColumnToTable() { exec("javascript:RE.addColumnToTable()"); } /** - * + * Deletes the currently selected column from the table in the Rich Editor WebView. + * This method executes a JavaScript command to delete the currently selected column from the table. */ public void deleteColumnFromTable() { exec("javascript:RE.deleteColumnFromTable()"); @@ -1012,21 +1087,17 @@ private void load(String trigger) { } /** - * @param cmdJS - * @return - */ - public boolean requestJSData(String cmdJS) { - // https://stackoverflow.com/questions/38380246/espresso-how-to-call-evaluatejavascript-on-a-webview - mEvaluateFinished.set(false); - - evaluateJavascript(cmdJS, this); - return true; - } - - /** - * + * A custom WebViewClient to handle page loading events for the RichEditor. + * This class extends the WebViewClient and provides additional functionality + * when a page has finished loading. */ protected class EditorWebViewClient extends WebViewClient { + /** + * Called when the page has finished loading in the WebView. + * + * @param view The WebView that has finished loading the page. + * @param url The URL of the page that has finished loading. + */ @Override public void onPageFinished(WebView view, String url) { isReady = url.equalsIgnoreCase(SETUP_HTML); From fe50f53f225c5d44df644f428ccbefed6087b20b Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 5 Jan 2024 22:58:54 +0100 Subject: [PATCH 106/136] clean up api for v3.0.0 insertVideo InsertYoutubeVideo InsertIFrame niendo1 --- richeditor/src/main/assets/rich_editor.js | 84 ++++++++++--- richeditor/src/main/assets/style.css | 4 +- .../jp/wasabeef/richeditor/RichEditor.java | 117 ++++++++++-------- .../java/jp/wasabeef/sample/MainActivity.java | 21 ++-- 4 files changed, 143 insertions(+), 83 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 5078eef..93129cc 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -468,32 +468,84 @@ RE.insertImage = function(url, alt="", width="", height="", relative="false") { //RE.callback("input"); }; -RE.insertVideo = function(url, alt="", width="", height="") { - var video = document.createElement('video'); - video.setAttribute("src", url); +RE.insertVideo = function(src, alt="", width="", height="", relative="false", optProperties="") { + if (optProperties == "") { + optProperties = "controls muted"; + } + var size = "xx"; + if (relative == "true") { + if (width == "") width = "100"; + if (height == "") + size = 'style="width:'+width+'%;"'; + else + size = 'style="width:'+width+'%; height: '+height+'%;"'; + } else { + if (width != "") + size = 'width="' + width + '"'; + if(height != "") + size = size + ' height="' + height + '"'; + } + + var html = '
' + RE.insertHTML(html); + +/* var video = document.createElement('video'); + video.setAttribute("src", src ); video.controls = true; video.muted = false; + //video.autoplay = true; if (alt != "") video.setAttribute("alt", alt); - - if (width == "auto") - video.setAttribute("width", "responsive-image"); - else if (width != "") { + if (relative == "true") { + if (width == "") width = "100"; + if (height == "") + video.setAttribute("style","width: "+width+"%;"); + else + video.setAttribute("style","width: "+width+"%; height: "+height+"%"); + } else { + if (width != "") video.setAttribute("width", width); - if (height != "") video.setAttribute("height", height); - } + if(height != "") + video.setAttribute("height", height); + } +// if (width == "auto") +// video.setAttribute("width", "responsive-image"); +// else if (width != "") { +// video.setAttribute("width", width); +// if (height != "") video.setAttribute("height", height); +// } video.onload = RE.updateHeight; - RE.insertHTML(video.outerHTML); + //RE.insertHTML(video.outerHTML); + var elements = document.querySelectorAll(":hover"); + elements[elements.length - 1].appendChild(video); //RE.callback("input"); +*/ } -RE.insertAudio = function(url, alt) { - var html = '
'; +RE.insertAudio = function(url, optProperties="") { + if (optProperties == "") { + optProperties = "controls"; + } + var html = '
'; RE.insertHTML(html); } -RE.insertYoutubeVideo = function(url, width="100%", height="100%") { - var html = '
' +RE.insertIFrame = function(src, name="", width="", height="", relative="false", optProperties="") { + var size = '' + if (relative == "true") { + if (width == "") width = "100"; + if (height == "") + size = 'style="width:'+width+'%;"'; + else + size = 'style="width:'+width+"%; height: "+height+'%"'; + } else { + if (width != "") + size = 'width="' + width + '"'; + if(height != "") + size = size + ' height="' + height + '"'; + } + + var html = '
' RE.insertHTML(html); } @@ -570,7 +622,7 @@ RE.insertHTML = function(html) { RE.insertLink = function(url, text, title) { RE.restorerange(); - document.execCommand("insertHTML",false,""+text+""); + RE.insertHTML(""+text+""); RE.setElementListener("link"); //RE.callback("input"); }; @@ -579,7 +631,7 @@ RE.insertLinkSelection = function(url, text, title) { RE.restorerange(); var sel = document.getSelection(); if (sel.toString().length == 0) { - document.execCommand("insertHTML",false,""+text+""); + RE.insertHTML(""+text+""); } else if (sel.rangeCount) { var el = document.createElement("a"); el.setAttribute("href", url); diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index bdef3e1..aba520e 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -79,11 +79,11 @@ input[type=checkbox] { height: auto; } -video { +/*video { width: 100% !important; height: auto !important; } - +*/ table {overflow-x: scroll;} th, td {max-width: 200px; min-width:50px;} table, td, th{border-collapse:collapse; border:1px solid #777;} diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 5d20cd9..fd52a4c 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -300,6 +300,31 @@ private void applyAttributes(Context context, AttributeSet attrs) { ta.recycle(); } + private void load(String trigger) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + evaluateJavascript(trigger, null); + } else { + loadUrl(trigger); + } + } + + + private String convertHexColorString(int color) { + return String.format("#%06X", (0xFFFFFF & color)); + } + + protected void exec(final String trigger) { + if (isReady) { + load(trigger); + } else { + postDelayed(new Runnable() { + @Override public void run() { + exec(trigger); + } + }, 100); + } + } + /** * Load html text in the the editor. *
@@ -831,7 +856,7 @@ public void setBlockquote() {
   public void setNumbers() { setOrderedList(); }
 
   /**
-   *
+   * Sets the selected text or cursor position to use an ordered list (numbers) in the Rich Editor WebView.
    */
   public void setOrderedList() { exec("javascript:RE.setOrderedList();"); }
 
@@ -919,14 +944,16 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h
    * Will show the original size of the video.
    * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens.
    *
-   * @param url
-   * @param alt
-   * @param width Width of the video; auto=100% page width
+   * @param url           The URI of the video to be inserted.
+   * @param alt           The alternative text for the video.
+   * @param width         The width of the video; if relative is true, 100 means 100% page width
+   * @param relative      Indicates if the video is relative to the page width.   *
+   * @param optProperties additional properties like 'autoplay muted controls loop'
    * @param height
    */
-  public void insertVideo(String url, String alt, String width, String height) {
+  public void insertVideo(String url, String alt, String width, String height, Boolean relative, String optProperties) {
     exec("javascript:RE.prepareInsert();");
-    exec("javascript:RE.insertVideo('" + url + "', '" + alt + "', '" + width + "' '" + height + "');");
+    exec("javascript:RE.insertVideo('" + url + "', '" + alt + "', '" + width + "','" + height + "', '" + relative.toString() + "', '" + optProperties + "');");
   }
 
   /**
@@ -935,42 +962,48 @@ public void insertVideo(String url, String alt, String width, String height) {
    * @param url The URL of the audio file to be inserted.
    * @param optProperties additional properties like 'autoplay, loop'
    */
-  public void insertAudio(String url) {
-    exec("javascript:RE.prepareInsert();");
-    exec("javascript:RE.insertAudio('" + url + "');");
-  }
-
-  /**
-   * @param url
-   */
-  public void insertYoutubeVideo(String url) {
+  public void insertAudio(String url, String optProperties) {
     exec("javascript:RE.prepareInsert();");
-    exec("javascript:RE.insertYoutubeVideo('" + url + "');");
+    exec("javascript:RE.insertAudio('" + url + "', '" + optProperties + "');");
   }
 
   /**
-   * @param url
-   * @param width
-   */
-  public void insertYoutubeVideo(String url, int width) {
+   * Embeds another HTML page (iframe) into the current one (like for YouTube video into the Rich Editor WebView with the specified URL, width, and height.
+   * This method executes JavaScript commands to prepare for video insertion and inserts the YouTube video.
+   *
+   * @param src    The src URL (for example https://www.openstreetmap.org/export/embed.html?bbox=12.236022949218752%2C51.28886912565582%2C12.462615966796877%2C51.39363622420581&layer=opnvkarte)
+   * @param name   alternative text, if the embedded page can not be shown.
+   * @param width  The width of the  embedded page.
+   * @param height The height of the embedded page.
+   * @param relative      Indicates if the frame size is relative to the page width.
+   * @param optProperties additional properties like 'title="test", allow-forms'
+   */
+  public void insertIFrame(String src, String name, String width, String height, Boolean relative, String optProperties) {
     exec("javascript:RE.prepareInsert();");
-    exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "');");
+    exec("javascript:RE.insertIFrame('" + src + "', '" + name + "', '" + "', '" + width + "', '" + height + "', '" + relative.toString() + "', '" + optProperties + "');");
   }
 
   /**
-   * @param url
-   * @param width
-   * @param height
+   * Inserts a YouTube video into the Rich Editor WebView with the specified URL, width, and height.
+   * This method executes JavaScript commands to prepare for video insertion and inserts the YouTube video.
+   * @see #insertIFrame
+   * @param src      The YouTube video URL. (for example https://www.youtube.com/embed/3AeYHDZ2riI)
+   * @param width    The width of the video player.
+   * @param height   The height of the video player.
+   * @param relative Indicates if the frame size is relative to the page width.
    */
-  public void insertYoutubeVideo(String url, int width, int height) {
-    exec("javascript:RE.prepareInsert();");
-    exec("javascript:RE.insertYoutubeVideo('" + url + "', '" + width + "', '" + height + "');");
+  public void insertYoutubeVideo(String src, String width, String height, Boolean relative) {
+    String optProperties="frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen\"";
+    exec("javascript:RE.insertIFrame('" + src + "', '', '" + width + "', '" + height + "', '" + relative.toString() + "', '" + optProperties + "');");
   }
 
   /**
-   * @param href
-   * @param text
-   * @param title
+   * Inserts a hyperlink into the Rich Editor WebView with the specified href, text, and title.
+   * This method executes JavaScript commands to prepare for link insertion and inserts the link.
+   *
+   * @param href  The URL to link to.
+   * @param text  The text to display as the link.
+   * @param title The title of the link (optional, can be null).
    */
   public void insertLink(String href, String text, String title) {
     exec("javascript:RE.prepareInsert();");
@@ -1010,22 +1043,6 @@ public void clearFocusEditor() {
     exec("javascript:RE.blurFocus();");
   }
 
-  private String convertHexColorString(int color) {
-    return String.format("#%06X", (0xFFFFFF & color));
-  }
-
-  protected void exec(final String trigger) {
-    if (isReady) {
-      load(trigger);
-    } else {
-      postDelayed(new Runnable() {
-        @Override public void run() {
-           exec(trigger);
-        }
-      }, 100);
-    }
-  }
-
   /**
    * Inserts a table with the specified number of columns and rows into the Rich Editor WebView.
    * This method executes JavaScript commands to prepare for table insertion and insert the table.
@@ -1078,14 +1095,6 @@ public void deleteColumnFromTable() {
     exec("javascript:RE.deleteColumnFromTable()");
   }
 
-  private void load(String trigger) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-      evaluateJavascript(trigger, null);
-    } else {
-      loadUrl(trigger);
-    }
-  }
-
   /**
    * A custom WebViewClient to handle page loading events for the RichEditor.
    * This class extends the WebViewClient and provides additional functionality
diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java
index a74be9c..09523b4 100644
--- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java
+++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java
@@ -311,38 +311,37 @@ public void onClick(View v) {
             if(!value.isEmpty()) {
               if(value.startsWith("https://www.youtube.com"))
                 value = value.replace("watch?v=","embed/");
-
-              // https://www.youtube.com/watch?v=3AeYHDZ2riI
-              // https://www.youtube.com/embed/3AeYHDZ2riI
-
-              mEditor.insertYoutubeVideo(value);
+                // https://www.youtube.com/watch?v=3AeYHDZ2riI
+                // https://www.youtube.com/embed/3AeYHDZ2riI
+              mEditor.insertYoutubeVideo(value,"","",true);
             }
             else
-              mEditor.insertHTML("Select a youtube link");
+              mEditor.insertHTML("Select a youtube link like: https://www.youtube.com/watch?v=3AeYHDZ2riI");
           }
         });
         mEditor.getSelectedText();
         //mEditor.insertYoutubeVideo("https://www.youtube.com/embed/pS5peqApgUA");
       }
-
-
-
     });
 
     findViewById(R.id.action_insert_audio).setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
-        mEditor.insertAudio("https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_5MG.mp3");
+        mEditor.insertAudio("https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_5MG.mp3", "");
       }
     });
 
     findViewById(R.id.action_insert_video).setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
-        mEditor.insertVideo("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_10MB.mp4","TestVideo" ,"360","");
+        mEditor.insertVideo("https://freetestdata.com/wp-content/uploads/2022/02/Free_Test_Data_10MB_MP4.mp4","TestVideo" ,"100","",true,"controls muted loop");
+
       }
     });
 
+
+
+
     findViewById(R.id.action_insert_link).setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {

From 336c077fa79e52b0a204db25edef6389897a7b42 Mon Sep 17 00:00:00 2001
From: niendo1 
Date: Sat, 6 Jan 2024 09:20:30 +0100
Subject: [PATCH 107/136] gradle 8.2.1

---
 build.gradle            | 2 +-
 richeditor/build.gradle | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/build.gradle b/build.gradle
index 758842b..778663e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
     mavenCentral()
   }
   dependencies {
-     classpath 'com.android.tools.build:gradle:8.2.0'
+     classpath 'com.android.tools.build:gradle:8.2.1'
   }
 }
 
diff --git a/richeditor/build.gradle b/richeditor/build.gradle
index 6709ac6..c9a2a93 100644
--- a/richeditor/build.gradle
+++ b/richeditor/build.gradle
@@ -19,7 +19,6 @@ android {
 
   buildTypes {
     release {
-      debuggable false
       minifyEnabled false
     }
   }

From 9d19ff5643c1e92f19bdc49328a6603de65198e9 Mon Sep 17 00:00:00 2001
From: niendo1 
Date: Mon, 8 Jan 2024 10:05:20 +0100
Subject: [PATCH 108/136] height and width of insert functions (video, image
 etc.)                  must be specified in units (px or %)

---
 richeditor/src/main/assets/rich_editor.js     | 18 +++---
 .../jp/wasabeef/richeditor/RichEditor.java    | 56 +++++++++++++------
 .../java/jp/wasabeef/sample/MainActivity.java |  4 +-
 3 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js
index 93129cc..7c5dfba 100644
--- a/richeditor/src/main/assets/rich_editor.js
+++ b/richeditor/src/main/assets/rich_editor.js
@@ -454,9 +454,9 @@ RE.insertImage = function(url, alt="", width="", height="", relative="false") {
     if (relative == "true") {
        if (width == "") width = "100";
          if (height == "")
-             img.setAttribute("style","width: "+width+"%;");
+             img.setAttribute("style","width: "+width+";");
          else
-             img.setAttribute("style","width: "+width+"%; height: "+height+"%");
+             img.setAttribute("style","width: "+width+"; height: "+height+";");
     } else {
        if (width != "")
           img.setAttribute("width", width);
@@ -472,13 +472,13 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op
    if (optProperties == "") {
       optProperties = "controls muted";
    }
-   var size = "xx";
+   var size = "";
    if (relative == "true") {
        if (width == "") width = "100";
          if (height == "")
-             size = 'style="width:'+width+'%;"';
+             size = 'style="width:'+width+';"';
          else
-             size = 'style="width:'+width+'%; height: '+height+'%;"';
+             size = 'style="width:'+width+'; height: '+height+';"';
     } else {
        if (width != "")
           size = 'width="' + width + '"';
@@ -498,9 +498,9 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op
     if (relative == "true") {
        if (width == "") width = "100";
          if (height == "")
-             video.setAttribute("style","width: "+width+"%;");
+             video.setAttribute("style","width: "+width+";");
          else
-             video.setAttribute("style","width: "+width+"%; height: "+height+"%");
+             video.setAttribute("style","width: "+width+"; height: "+height+"");
     } else {
        if (width != "")
           video.setAttribute("width", width);
@@ -535,9 +535,9 @@ RE.insertIFrame = function(src, name="", width="", height="", relative="false",
    if (relative == "true") {
        if (width == "") width = "100";
          if (height == "")
-             size = 'style="width:'+width+'%;"';
+             size = 'style="width:'+width+';"';
          else
-             size = 'style="width:'+width+"%; height: "+height+'%"';
+             size = 'style="width:'+width+"; height: "+height+';"';
     } else {
        if (width != "")
           size = 'width="' + width + '"';
diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java
index fd52a4c..67ed423 100644
--- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java
+++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java
@@ -431,7 +431,7 @@ public boolean getSelectedHref() {
   /**
    * Whether or not the selection has a type specifically of "Range".
    * Data comes via callback.
-   * @see #getHtml
+   * @see #getHtml()
    * @return
    */
   public boolean hasRangeSelection() {
@@ -618,7 +618,7 @@ public void redo() {
   }
 
   /**
-   * set html tag 
 
+ * set html tag PRE */ public void setPre() { exec("javascript:RE.setPre();"); @@ -840,7 +840,7 @@ public void setBlockquote() { /** * Sets the selected text or cursor position to use bullets in the Rich Editor WebView. - * This method is an alias for {@link #setUnorderedList()}. + * This method is an alias for {@see #setUnorderedList()}. */ public void setBullets() { setUnorderedList(); } @@ -851,7 +851,7 @@ public void setBlockquote() { /** * Sets the selected text or cursor position to use numbers in the Rich Editor WebView. - * This method is an alias for {@link #setOrderedList()}. + * This method is an alias for {@see #setOrderedList()}. */ public void setNumbers() { setOrderedList(); } @@ -862,6 +862,10 @@ public void setBlockquote() { /** * Insert a HTML string into the Rich Editor WebView. + * Example to insert a not breakable space: + *
+   *   mEditor.insertHTML(" ";)
+   * 
* @param text */ public void insertHTML(String text) { @@ -894,11 +898,20 @@ public void insertCollapsibleSection(String section, String content) { /** * Inserts an image into the Rich Editor as link * So this method can manually process the image by adjusting specific width and height to fit into different mobile screens. + * Example to insert + *
+   *   // inserts an image with 90% page width
+   *   mEditor.insertImage("https://.. .jpg", "Example", "90%", "", true);
+   *   // inserts an image with 50% of its own width
+   *   mEditor.insertImage("https://.. .jpg", "Example", "50%", "", false);
+   * 
* * @param url The URI of the image to be inserted. * @param alt The alternative text for the image. - * @param width Width of the Image; if relative=true then 100 means 100% page width - * @param height Height of the Image + * @param width Width of the Image; if relative=true then 100% means 100% page width. + * Can be empty, must be specified in units (px or %) + * @param height Height of the Image (with units). + * Can be empty, must be specified in units (px or %) * @param relative Image size is relative to page width */ public void insertImage(String url, String alt, String width, String height, Boolean relative) { @@ -912,9 +925,11 @@ public void insertImage(String url, String alt, String width, String height, Boo * * @param imageURI The URI of the image to be inserted. * @param alt The alternative text for the image. - * @param width The width of the image; if relative is true, 100 means 100% page width. + * @param width The width of the image; if relative=true then 100% means 100% page width. + * Can be empty, must be specified in units (px or %) * @param height The height of the image. - * @param relative Indicates if the image size is relative to the page width. + * Can be empty, must be specified in units (px or %) + * @param relative Image size is relative to page width * @param inSampleSize Shrink the image size. */ public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative, Integer inSampleSize) { @@ -946,8 +961,11 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h * * @param url The URI of the video to be inserted. * @param alt The alternative text for the video. - * @param width The width of the video; if relative is true, 100 means 100% page width - * @param relative Indicates if the video is relative to the page width. * + * @param width The width of the video; if relative=true then 100% means 100% page width. + * Can be empty, must be specified in units (px or %) + * @param height The height of the image. + * Can be empty, must be specified in units (px or %) + * @param relative Video size is relative to page width * @param optProperties additional properties like 'autoplay muted controls loop' * @param height */ @@ -973,9 +991,11 @@ public void insertAudio(String url, String optProperties) { * * @param src The src URL (for example https://www.openstreetmap.org/export/embed.html?bbox=12.236022949218752%2C51.28886912565582%2C12.462615966796877%2C51.39363622420581&layer=opnvkarte) * @param name alternative text, if the embedded page can not be shown. - * @param width The width of the embedded page. - * @param height The height of the embedded page. - * @param relative Indicates if the frame size is relative to the page width. + * @param width The width of the frame; if relative=true then 100% means 100% page width. + * Can be empty, must be specified in units (px or %) + * @param height The height of the image. + * Can be empty, must be specified in units (px or %) + * @param relative Frame size is relative to page width * @param optProperties additional properties like 'title="test", allow-forms' */ public void insertIFrame(String src, String name, String width, String height, Boolean relative, String optProperties) { @@ -988,9 +1008,11 @@ public void insertIFrame(String src, String name, String width, String height, B * This method executes JavaScript commands to prepare for video insertion and inserts the YouTube video. * @see #insertIFrame * @param src The YouTube video URL. (for example https://www.youtube.com/embed/3AeYHDZ2riI) - * @param width The width of the video player. - * @param height The height of the video player. - * @param relative Indicates if the frame size is relative to the page width. + * @param width The width of the video; if relative=true then 100% means 100% page width + * Can be empty, must be specified in units (px or %) + * @param height The height of the image + * Can be empty, must be specified in units (px or %) + * @param relative Video size is relative to page width */ public void insertYoutubeVideo(String src, String width, String height, Boolean relative) { String optProperties="frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen\""; @@ -1003,7 +1025,7 @@ public void insertYoutubeVideo(String src, String width, String height, Boolean * * @param href The URL to link to. * @param text The text to display as the link. - * @param title The title of the link (optional, can be null). + * @param title The title of the link (optional, can be empty). */ public void insertLink(String href, String text, String title) { exec("javascript:RE.prepareInsert();"); diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 09523b4..8f19d33 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -297,7 +297,7 @@ public void onClick(View v) { // image="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Hyoscyamus_niger_0003.JPG/449px-Hyoscyamus_niger_0003.JPG"; // image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; //mEditor.insertImageAsBase64(Uri.parse(image),"alt","auto",""); - mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "","",true); + mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "75%","",true); } }); @@ -334,7 +334,7 @@ public void onClick(View v) { findViewById(R.id.action_insert_video).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mEditor.insertVideo("https://freetestdata.com/wp-content/uploads/2022/02/Free_Test_Data_10MB_MP4.mp4","TestVideo" ,"100","",true,"controls muted loop"); + mEditor.insertVideo("https://freetestdata.com/wp-content/uploads/2022/02/Free_Test_Data_10MB_MP4.mp4","TestVideo" ,"100%","",true,"controls muted loop"); } }); From eccae7e02c09c0ff209e79a8fa54f21d3ddce14e Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 11 Jan 2024 12:46:42 +0100 Subject: [PATCH 109/136] fixes for InsertImage --- richeditor/src/main/assets/rich_editor.js | 19 +++++++----- richeditor/src/main/assets/style.css | 5 +-- .../jp/wasabeef/richeditor/RichEditor.java | 31 ++++++++++--------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 7c5dfba..53cc683 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -452,16 +452,19 @@ RE.insertImage = function(url, alt="", width="", height="", relative="false") { img.setAttribute("src", url); if (alt != "") img.setAttribute("alt", alt); if (relative == "true") { - if (width == "") width = "100"; + if (width == "") width = "100%"; if (height == "") img.setAttribute("style","width: "+width+";"); else img.setAttribute("style","width: "+width+"; height: "+height+";"); } else { - if (width != "") - img.setAttribute("width", width); - if(height != "") - img.setAttribute("height", height); + // for % of image size, width must be empty! + if ((width.search("%") != -1) && (height == "")) { + height = width; + width = ""; + } + img.setAttribute("width", width); + img.setAttribute("height", height); } img.onload = RE.updateHeight; RE.insertHTML(img.outerHTML); @@ -474,7 +477,7 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op } var size = ""; if (relative == "true") { - if (width == "") width = "100"; + if (width == "") width = "100%"; if (height == "") size = 'style="width:'+width+';"'; else @@ -496,7 +499,7 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op //video.autoplay = true; if (alt != "") video.setAttribute("alt", alt); if (relative == "true") { - if (width == "") width = "100"; + if (width == "") width = "100%"; if (height == "") video.setAttribute("style","width: "+width+";"); else @@ -533,7 +536,7 @@ RE.insertAudio = function(url, optProperties="") { RE.insertIFrame = function(src, name="", width="", height="", relative="false", optProperties="") { var size = '' if (relative == "true") { - if (width == "") width = "100"; + if (width == "") width = "100%"; if (height == "") size = 'style="width:'+width+';"'; else diff --git a/richeditor/src/main/assets/style.css b/richeditor/src/main/assets/style.css index aba520e..817632f 100644 --- a/richeditor/src/main/assets/style.css +++ b/richeditor/src/main/assets/style.css @@ -74,16 +74,17 @@ input[type=checkbox] { margin-right: 9px; } -#responsive-image { +/* #responsive-image { width: 100%; height: auto; } -/*video { +video { width: 100% !important; height: auto !important; } */ + table {overflow-x: scroll;} th, td {max-width: 200px; min-width:50px;} table, td, th{border-collapse:collapse; border:1px solid #777;} diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 67ed423..b5bbdf9 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -51,6 +51,7 @@ /** * This class provides the HTML-Editor. * + * Note: The behavior may vary between different Android, Java and webView versions */ public class RichEditor extends WebView implements ValueCallback { @@ -901,17 +902,19 @@ public void insertCollapsibleSection(String section, String content) { * Example to insert *
    *   // inserts an image with 90% page width
-   *   mEditor.insertImage("https://.. .jpg", "Example", "90%", "", true);
+   *   mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "Example", "90%", "", true);
    *   // inserts an image with 50% of its own width
-   *   mEditor.insertImage("https://.. .jpg", "Example", "50%", "", false);
+   *   mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "Example", "50%", "", false);
+   *   // inserts an image 100px X 100px
+   *   mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "100","100",false);
    * 
* * @param url The URI of the image to be inserted. * @param alt The alternative text for the image. * @param width Width of the Image; if relative=true then 100% means 100% page width. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param height Height of the Image (with units). - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param relative Image size is relative to page width */ public void insertImage(String url, String alt, String width, String height, Boolean relative) { @@ -922,15 +925,15 @@ public void insertImage(String url, String alt, String width, String height, Boo /** * Inserts an image into the Rich Editor WebView using Base64 encoding from the provided image URI. * This method allows manual processing of the image, adjusting width and height to fit different mobile screens. - * + * Examples: * @param imageURI The URI of the image to be inserted. * @param alt The alternative text for the image. * @param width The width of the image; if relative=true then 100% means 100% page width. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param height The height of the image. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param relative Image size is relative to page width - * @param inSampleSize Shrink the image size. + * @param inSampleSize Shrink the image size by this factor. */ public void insertImageAsBase64(Uri imageURI, String alt, String width, String height, Boolean relative, Integer inSampleSize) { InputStream inputStream = null; @@ -962,9 +965,9 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h * @param url The URI of the video to be inserted. * @param alt The alternative text for the video. * @param width The width of the video; if relative=true then 100% means 100% page width. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param height The height of the image. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param relative Video size is relative to page width * @param optProperties additional properties like 'autoplay muted controls loop' * @param height @@ -992,9 +995,9 @@ public void insertAudio(String url, String optProperties) { * @param src The src URL (for example https://www.openstreetmap.org/export/embed.html?bbox=12.236022949218752%2C51.28886912565582%2C12.462615966796877%2C51.39363622420581&layer=opnvkarte) * @param name alternative text, if the embedded page can not be shown. * @param width The width of the frame; if relative=true then 100% means 100% page width. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param height The height of the image. - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param relative Frame size is relative to page width * @param optProperties additional properties like 'title="test", allow-forms' */ @@ -1009,9 +1012,9 @@ public void insertIFrame(String src, String name, String width, String height, B * @see #insertIFrame * @param src The YouTube video URL. (for example https://www.youtube.com/embed/3AeYHDZ2riI) * @param width The width of the video; if relative=true then 100% means 100% page width - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param height The height of the image - * Can be empty, must be specified in units (px or %) + * Can be empty, if not specified in units (px or %) its px * @param relative Video size is relative to page width */ public void insertYoutubeVideo(String src, String width, String height, Boolean relative) { From a1c024bc422bf9481ea5c80762539c7ac806c424 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 11 Jan 2024 12:49:00 +0100 Subject: [PATCH 110/136] version 3.0.0 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e3eb06d..382d2fb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0pre9 -VERSION_CODE=290 +VERSION_NAME=3.0.0 +VERSION_CODE=300 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=34 From 1e5837b6c9766cd9679bf50abcb7f3f1ba708884 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 16 Feb 2024 09:40:01 +0100 Subject: [PATCH 111/136] fix readme: How do I use it? solves #1 --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c2e192..1e8ab69 100644 --- a/README.md +++ b/README.md @@ -93,17 +93,55 @@ How do I use it? ##### Gradle -```groovy +```gradle repositories { mavenCentral() maven { url "https://jitpack.io" } } dependencies { - implementation 'com.github.jitpack:richeditor-android:3.0.0' + implementation 'com.github.niendo1:richeditor-android:3.0.0' } ``` +##### Maven + +```xml + + + jitpack.io + https://jitpack.io + + +``` + +```xml + + com.github.niendo1 + richeditor-android + 3.0.0 + + +``` + +##### leiningen + +```leiningen + +:repositories [["jitpack" "https://jitpack.io"]] +:dependencies [[com.github.niendo1/richeditor-android "3.0.0"]] + +``` + +##### sbt + +```sbt + +resolvers += "jitpack" at "https://jitpack.io" +libraryDependencies += "com.github.niendo1" % "richeditor-android" % "3.0.0" + +``` + ### Default Setting for Editor --- From 11d95bfc5a322bf4ec0a3e360b5c166d447c3bc1 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sat, 24 Feb 2024 00:04:45 +0100 Subject: [PATCH 112/136] insertHTML now according to setHTML --- CHANGELOG.md | 15 ++++++++++++++- .../jp/wasabeef/richeditor/RichEditor.java | 18 +++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4264f45..0d69afa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ Change Log ========== +Version 3.0.1 *(2024-)* +---------------------------- + +Bugfix: +- insertHTML now according to setHTML + + +Version 3.0.0 *(2024-01-11)* +---------------------------- + +Feature: +- New version, new author: lot of changes + Version 2.0.0 *(2020-09-16)* ---------------------------- @@ -14,7 +27,7 @@ Update: Bugfix: - Fixed placeholder [#240](https://github.com/wasabeef/richeditor-android/pull/240) -- Fixed typp [#194](https://github.com/wasabeef/richeditor-android/pull/194) +- Fixed typo [#194](https://github.com/wasabeef/richeditor-android/pull/194) - Fixed Url decoding [#123](https://github.com/wasabeef/richeditor-android/pull/123) - Fixed shouldOverrideUrlLoading [#133](https://github.com/wasabeef/richeditor-android/pull/133) - Use encodeURIComponent() [#145](https://github.com/wasabeef/richeditor-android/pull/145) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index b5bbdf9..6dbff9d 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -867,14 +867,18 @@ public void setBlockquote() { *
    *   mEditor.insertHTML(" ";)
    * 
- * @param text + * @param contents string with html content */ - public void insertHTML(String text) { - exec("javascript:RE.prepareInsert();"); - text = text.replace("\n", "
") - .replace("\\", "\\\\") - .replace("\"", "\\\""); // unescape \\ -> \ - exec("javascript:RE.insertHTML('" + text + "');"); + public void insertHTML(String contents) { + if (contents == null) { + contents = ""; + } + try { + exec("javascript:RE.prepareInsert();"); + exec("javascript:RE.insertHTML('" + URLEncoder.encode(contents, "UTF-8") + "');"); + } catch (UnsupportedEncodingException e) { + // No handling + } } /** From 147b697bc4eb26e95fe4012baff11ece45c70905 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 26 Feb 2024 18:21:29 +0100 Subject: [PATCH 113/136] insertHTML now according to setHTML --- richeditor/src/main/assets/rich_editor.js | 27 ++++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 53cc683..61150a4 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -338,7 +338,7 @@ RE.LoadFont = function LoadFont(name, url) { document.fonts.add(loadedFont); //do something after the font is loaded }).catch(function(error) { - RE.insertHTML(error) + RE._insertHTML(error) // error occurred }); } @@ -417,7 +417,7 @@ function createCheckbox(node) { RE.setCheckbox = function() { var el = document.createElement("input"); el.setAttribute("type", "checkbox"); - RE.insertHTML(" " + el.outerHTML + " "); + RE._insertHTML(" " + el.outerHTML + " "); RE.setElementListener("checkbox"); //RE.callback("input"); }; @@ -467,7 +467,7 @@ RE.insertImage = function(url, alt="", width="", height="", relative="false") { img.setAttribute("height", height); } img.onload = RE.updateHeight; - RE.insertHTML(img.outerHTML); + RE._insertHTML(img.outerHTML); //RE.callback("input"); }; @@ -490,7 +490,7 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op } var html = '
' - RE.insertHTML(html); + RE._insertHTML(html); /* var video = document.createElement('video'); video.setAttribute("src", src ); @@ -518,7 +518,7 @@ RE.insertVideo = function(src, alt="", width="", height="", relative="false", op // } video.onload = RE.updateHeight; - //RE.insertHTML(video.outerHTML); + //RE._insertHTML(video.outerHTML); var elements = document.querySelectorAll(":hover"); elements[elements.length - 1].appendChild(video); //RE.callback("input"); @@ -530,7 +530,7 @@ RE.insertAudio = function(url, optProperties="") { optProperties = "controls"; } var html = '
'; - RE.insertHTML(html); + RE._insertHTML(html); } RE.insertIFrame = function(src, name="", width="", height="", relative="false", optProperties="") { @@ -549,7 +549,7 @@ RE.insertIFrame = function(src, name="", width="", height="", relative="false", } var html = '
' - RE.insertHTML(html); + RE._insertHTML(html); } RE.setElementListener = function(element) { @@ -618,14 +618,19 @@ RE.insertCollapsibleSection = function(section, content) { RE.setElementListener("section"); } -RE.insertHTML = function(html) { +RE._insertHTML = function(html) { RE.restorerange(); document.execCommand('insertHTML', false, html); }; +RE.insertHTML = function(contents) { + RE.restorerange(); + document.execCommand('insertHTML', false, decodeURIComponent(contents.replace(/\+/g, '%20')); +}; + RE.insertLink = function(url, text, title) { RE.restorerange(); - RE.insertHTML(""+text+""); + RE._insertHTML(""+text+""); RE.setElementListener("link"); //RE.callback("input"); }; @@ -634,7 +639,7 @@ RE.insertLinkSelection = function(url, text, title) { RE.restorerange(); var sel = document.getSelection(); if (sel.toString().length == 0) { - RE.insertHTML(""+text+""); + RE._insertHTML(""+text+""); } else if (sel.rangeCount) { var el = document.createElement("a"); el.setAttribute("href", url); @@ -699,7 +704,7 @@ RE.insertTable = function(width, height) { var cell = row.insertCell(); } } - RE.insertHTML(table.outerHTML); + RE._insertHTML(table.outerHTML); RE.setNewParagraph(); //RE.callback("input"); }; From b54e55a10e2d28fd0dc6f95252a80f50250a3467 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 26 Feb 2024 20:01:30 +0100 Subject: [PATCH 114/136] insertHTML now according to setHTML --- richeditor/src/main/assets/rich_editor.js | 4 ++-- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 61150a4..d6709e2 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2022-2023 peter@niendo.de + * Copyright (C) 2022-2024 peter@niendo.de * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2015 Wasabeef * @@ -625,7 +625,7 @@ RE._insertHTML = function(html) { RE.insertHTML = function(contents) { RE.restorerange(); - document.execCommand('insertHTML', false, decodeURIComponent(contents.replace(/\+/g, '%20')); + document.execCommand('insertHTML', false, decodeURIComponent(contents.replace(/\+/g, '%20'))); }; RE.insertLink = function(url, text, title) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 6dbff9d..e8345e3 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** - * Copyright (C) 2022-2023 niendo + * Copyright (C) 2022-2024 niendo * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2020 Wasabeef *

From bd9b2552ba86af8cdfc20a7c53a532d0d602a465 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 26 Feb 2024 20:25:26 +0100 Subject: [PATCH 115/136] update gradle and target version v3.0.1 --- CHANGELOG.md | 10 +++++++--- build.gradle | 2 +- gradle.properties | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d69afa..715ae9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,22 @@ Change Log ========== -Version 3.0.1 *(2024-)* +Version 3.0.1 *(2024-02-26)* ---------------------------- Bugfix: -- insertHTML now according to setHTML +- insertHTML now according to setHTML + +Update: +- gradle:8.2.2 +- Compile / Target SDK Version 3x -> 34 Version 3.0.0 *(2024-01-11)* ---------------------------- Feature: -- New version, new author: lot of changes +- New version, new author: lots of changes Version 2.0.0 *(2020-09-16)* ---------------------------- diff --git a/build.gradle b/build.gradle index 778663e..902a1e1 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.2.1' + classpath 'com.android.tools.build:gradle:8.2.2' } } diff --git a/gradle.properties b/gradle.properties index 382d2fb..28d46b1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,12 +19,12 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.0 -VERSION_CODE=300 +VERSION_NAME=3.0.1 +VERSION_CODE=301 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=34 -TARGET_SDK_VERSION=33 +TARGET_SDK_VERSION=34 MIN_SDK_VERSION=24 #android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false From b8d83b36b2edc3d7174d6959e5427fd7f81474f2 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 21:37:52 +0200 Subject: [PATCH 116/136] add requestFocusFromTouch(); --- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 2 ++ sample/src/main/java/jp/wasabeef/sample/MainActivity.java | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index e8345e3..e82fd30 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -713,6 +713,7 @@ public void setTextColor(int color) { * @param color */ public void setTextColor(String color) { + requestFocusFromTouch(); exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextColor('" + color + "');"); } @@ -734,6 +735,7 @@ public void setTextBackgroundColor(int color) { * @param color as string */ public void setTextBackgroundColor(String color) { + requestFocusFromTouch(); exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextBackgroundColor('" + color + "');"); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 8f19d33..5bf6c0c 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -190,7 +190,9 @@ public void onClick(View v) { @Override public void onDataReceived(String value) { if(!value.isEmpty()) mEditor.setTextColor(value); - } + else + mEditor.setTextColor("green"); + } }); mEditor.getSelectedText(); From 4a12e99da40ebe64e6126a0370bf2662b77ec594 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 21:51:23 +0200 Subject: [PATCH 117/136] jitpack trouble --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index 3928e84..b28d689 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk21 + - openjdk20 before_install: - ./scripts/prepareJitpackEnvironment.sh From a8e220b9f7724c665be4faa97b664798f2a5da9d Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 21:57:49 +0200 Subject: [PATCH 118/136] jitpack trouble --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 3 ++- jitpack.yml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 902a1e1..839473c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.2.2' + classpath 'com.android.tools.build:gradle:8.3.2' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..2172537 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Wed Apr 10 21:55:39 CEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/jitpack.yml b/jitpack.yml index b28d689..3928e84 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk20 + - openjdk21 before_install: - ./scripts/prepareJitpackEnvironment.sh From 14b3e4132f78a6c8123abb524ee283e09dd93f09 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 22:00:05 +0200 Subject: [PATCH 119/136] jitpack trouble --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index 3928e84..69ed826 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk21 + - openjdk9 before_install: - ./scripts/prepareJitpackEnvironment.sh From 93854048e3c7e83eb00eb82d8e2d64e6107c8954 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 22:01:29 +0200 Subject: [PATCH 120/136] jitpack trouble --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index 69ed826..b28d689 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk9 + - openjdk20 before_install: - ./scripts/prepareJitpackEnvironment.sh From 845e4322d9b7e5232c5b6f69de768f728a1a55f6 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 22:08:16 +0200 Subject: [PATCH 121/136] jitpack trouble --- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 1 - gradlew.bat | 20 ++++++++++---------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch delta 34118 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 delta 34176 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 SGW6ptSs!X7{rG*o_g?|vpSEZK diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2172537..b82aa23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,3 @@ -#Wed Apr 10 21:55:39 CEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip diff --git a/gradlew.bat b/gradlew.bat index 6689b85..7101f8e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From fd9338203c2bd7b62a43cb78fcc8da3fdddf87c1 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 10 Apr 2024 22:20:11 +0200 Subject: [PATCH 122/136] jitpack trouble --- gradle/wrapper/gradle-wrapper.properties | 2 +- jitpack.yml | 2 +- richeditor/build.gradle | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23..e7646de 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/jitpack.yml b/jitpack.yml index b28d689..f82bf6a 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk20 + - openjdk17 before_install: - ./scripts/prepareJitpackEnvironment.sh diff --git a/richeditor/build.gradle b/richeditor/build.gradle index c9a2a93..734971a 100644 --- a/richeditor/build.gradle +++ b/richeditor/build.gradle @@ -42,8 +42,8 @@ afterEvaluate { name = "GitHubPackages" url = uri("https://maven.pkg.github.com/niendo1/richeditor-android") credentials { - username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") - password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") + username = "unused" //project.findProperty("gpr.user") ?: System.getenv("USERNAME") + password = "unused" //project.findProperty("gpr.key") ?: System.getenv("TOKEN") } } } From a82b781ac1fffc81ab1c79c263bf9ff5cfc96059 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 11 Apr 2024 16:28:49 +0200 Subject: [PATCH 123/136] requestFocusFromTouchTest --- .../src/main/java/jp/wasabeef/richeditor/RichEditor.java | 5 ++--- .../src/main/java/jp/wasabeef/sample/MainActivity.java | 9 +++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index e82fd30..09bc1db 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -713,7 +713,7 @@ public void setTextColor(int color) { * @param color */ public void setTextColor(String color) { - requestFocusFromTouch(); + //requestFocusFromTouch(); exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextColor('" + color + "');"); } @@ -723,7 +723,6 @@ public void setTextColor(String color) { * @param color */ public void setTextBackgroundColor(int color) { - setTextBackgroundColor(convertHexColorString(color)); } @@ -735,7 +734,7 @@ public void setTextBackgroundColor(int color) { * @param color as string */ public void setTextBackgroundColor(String color) { - requestFocusFromTouch(); + //requestFocusFromTouch(); exec("javascript:RE.prepareInsert();"); exec("javascript:RE.setTextBackgroundColor('" + color + "');"); } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 5bf6c0c..6a9d285 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -292,14 +292,15 @@ public void onClick(View v) { findViewById(R.id.action_insert_image).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - String image; - image=getContentResolver().SCHEME_ANDROID_RESOURCE + - "://" + getResources().getResourcePackageName(R.drawable.insert_image) - + '/' + getResources().getResourceTypeName(R.drawable.insert_image) + '/' + getResources().getResourceEntryName(R.drawable.bg_color); + // String image; + // image=getContentResolver().SCHEME_ANDROID_RESOURCE + + // "://" + getResources().getResourcePackageName(R.drawable.insert_image) + // + '/' + getResources().getResourceTypeName(R.drawable.insert_image) + '/' + getResources().getResourceEntryName(R.drawable.bg_color); // image="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Hyoscyamus_niger_0003.JPG/449px-Hyoscyamus_niger_0003.JPG"; // image="https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg"; //mEditor.insertImageAsBase64(Uri.parse(image),"alt","auto",""); mEditor.insertImage("https://raw.githubusercontent.com/wasabeef/art/master/chip.jpg", "dachshund", "75%","",true); + //mEditor.insertHTML("Logo"); } }); From fdd0b880e7f721440374b0a678e8bd68b96d5a54 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 11 Apr 2024 19:00:39 +0200 Subject: [PATCH 124/136] setTextColor("") resets to default color --- richeditor/src/main/assets/rich_editor.js | 2 ++ .../jp/wasabeef/richeditor/RichEditor.java | 2 ++ .../java/jp/wasabeef/sample/MainActivity.java | 20 +++++++++++-------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index d6709e2..a592aeb 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -315,6 +315,7 @@ RE.toggleUnderline = function() { RE.setTextColor = function(color) { RE.restorerange(); + if(color == "") color = RE.editor.style.color; document.execCommand("styleWithCSS", null, true); document.execCommand('foreColor', false, color); document.execCommand("styleWithCSS", null, false); @@ -322,6 +323,7 @@ RE.setTextColor = function(color) { RE.setTextBackgroundColor = function(color) { RE.restorerange(); + if(color == "") color = RE.editor.style.backgroundColor; document.execCommand("styleWithCSS", null, true); document.execCommand('hiliteColor', false, color); document.execCommand("styleWithCSS", null, false); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 09bc1db..2b3888d 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -707,6 +707,7 @@ public void setTextColor(int color) { /** * set text color by string + * if color isEmpty(), text color is reset to default value *
        *   mEditor.setTextColor("red")
        * 
    @@ -728,6 +729,7 @@ public void setTextBackgroundColor(int color) { /** * Sets Background color for text by string + * if color isEmpty(), background color is reset to default value *
        * mEditor.setTextColor("red")
        * 
    diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 6a9d285..ec9fb7e 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -1,10 +1,7 @@ package jp.wasabeef.sample; -import android.content.Intent; import android.graphics.Color; -import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.View; import android.widget.TextView; @@ -188,16 +185,20 @@ public void onClick(View v) { // so the selected text is for example 'green', the colored green mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { @Override public void onDataReceived(String value) { - if(!value.isEmpty()) - mEditor.setTextColor(value); + if(!value.isEmpty()) { + if (isChanged) + mEditor.setTextColor(""); + else + mEditor.setTextColor(Color.CYAN); + isChanged = !isChanged; + } else mEditor.setTextColor("green"); } }); mEditor.getSelectedText(); - //mEditor.setTextColor(isChanged ? Color.BLACK : Color.RED); - //isChanged = !isChanged; + } }); @@ -206,7 +207,10 @@ public void onClick(View v) { @Override public void onClick(View v) { - mEditor.setTextBackgroundColor(isChanged ? Color.TRANSPARENT : Color.YELLOW); + if (isChanged) + mEditor.setTextBackgroundColor(""); + else + mEditor.setTextBackgroundColor(Color.GREEN); isChanged = !isChanged; } }); From 73f08727fcc09bd6cb9970f31325fda8bc1a7056 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Thu, 11 Apr 2024 21:28:05 +0200 Subject: [PATCH 125/136] setTextColor("initial") resets to default color --- CHANGELOG.md | 15 +++++++++++++++ richeditor/src/main/assets/rich_editor.js | 3 +-- .../java/jp/wasabeef/richeditor/RichEditor.java | 4 ++-- .../java/jp/wasabeef/sample/MainActivity.java | 8 ++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 715ae9a..c299710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ Change Log ========== +Version 3.0.4 *(2024-04-)* +---------------------------- + +Bugfix: + +Feature: +- setTextColor("initial") resets to default text color +- setBackgroundColor("initial") resets to default background color + +Update: +- gradle:8.3.2 +- openjdk17 from 21 for jitpack +- gradle-8.7 + + Version 3.0.1 *(2024-02-26)* ---------------------------- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index a592aeb..8a00c04 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -315,7 +315,7 @@ RE.toggleUnderline = function() { RE.setTextColor = function(color) { RE.restorerange(); - if(color == "") color = RE.editor.style.color; + if(color == "initial") color = RE.editor.style.color; document.execCommand("styleWithCSS", null, true); document.execCommand('foreColor', false, color); document.execCommand("styleWithCSS", null, false); @@ -323,7 +323,6 @@ RE.setTextColor = function(color) { RE.setTextBackgroundColor = function(color) { RE.restorerange(); - if(color == "") color = RE.editor.style.backgroundColor; document.execCommand("styleWithCSS", null, true); document.execCommand('hiliteColor', false, color); document.execCommand("styleWithCSS", null, false); diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 2b3888d..5de4ee3 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -707,7 +707,7 @@ public void setTextColor(int color) { /** * set text color by string - * if color isEmpty(), text color is reset to default value + * if color=initial, text color is reset to default value *
        *   mEditor.setTextColor("red")
        * 
    @@ -729,7 +729,7 @@ public void setTextBackgroundColor(int color) { /** * Sets Background color for text by string - * if color isEmpty(), background color is reset to default value + * if color=initial, background color is reset to default value *
        * mEditor.setTextColor("red")
        * 
    diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index ec9fb7e..7263d51 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -186,14 +186,14 @@ public void onClick(View v) { mEditor.setOnJSDataListener(new RichEditor.onJSDataListener() { @Override public void onDataReceived(String value) { if(!value.isEmpty()) { + mEditor.setTextColor("green"); + } else { if (isChanged) - mEditor.setTextColor(""); + mEditor.setTextColor("initial"); else mEditor.setTextColor(Color.CYAN); isChanged = !isChanged; } - else - mEditor.setTextColor("green"); } }); @@ -208,7 +208,7 @@ public void onClick(View v) { @Override public void onClick(View v) { if (isChanged) - mEditor.setTextBackgroundColor(""); + mEditor.setTextBackgroundColor("initial"); else mEditor.setTextBackgroundColor(Color.GREEN); isChanged = !isChanged; From a32bc31cc132120042ec652ecf45a18acc99ae49 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 12 Apr 2024 13:22:25 +0200 Subject: [PATCH 126/136] add onWindowFocusChanged() by IntuzMayurS --- .../jp/wasabeef/richeditor/RichEditor.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index 5de4ee3..ec43662 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -13,6 +13,7 @@ import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; +import android.view.inputmethod.InputMethodManager; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; @@ -64,6 +65,24 @@ public enum Type { private final AtomicBoolean mEvaluateFinished = new AtomicBoolean(false); + + /** + * Bring back focus in to the editor + * by IntuzMayurS + * + */ + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + if (hasWindowFocus) { + requestFocus(); + post(() -> { + InputMethodManager imm = getContext().getSystemService(InputMethodManager.class); + imm.showSoftInput(this, 0); + }); + } + } + /** * Callback interface to receive data from the editor * From 4b12a42385ca5e8dcde690d05e5bd71e87cff797 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 12 Apr 2024 13:53:32 +0200 Subject: [PATCH 127/136] ReadMe/ChangeLog --- CHANGELOG.md | 5 +++-- README.md | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c299710..42df7ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ Change Log ========== -Version 3.0.4 *(2024-04-)* +Version 3.0.2 *(2024-04-)* ---------------------------- Bugfix: - +- add onWindowFocusChanged() by IntuzMayurS + Feature: - setTextColor("initial") resets to default text color - setBackgroundColor("initial") resets to default background color diff --git a/README.md b/README.md index 1e8ab69..1eacee9 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,8 @@ editor.setEditorHeight(200); ```java editor.setEditorFontSize(22); editor.setEditorFontColor(Color.RED); +editor.setTextColor("initial"); +editor.setFontFamily("fantasy"); ``` **Background** @@ -247,7 +249,7 @@ Thanks License ------- - Copyright (C) 2022-2023 niendo + Copyright (C) 2022-2024 niendo Copyright (C) 2020 Wasabeef Licensed under the Apache License, Version 2.0 (the "License"); From 277e37a34de824704a54403362a1261417dce58a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 15 Apr 2024 18:10:38 +0200 Subject: [PATCH 128/136] v3.0.2 --- CHANGELOG.md | 2 +- README.md | 8 ++++---- gradle.properties | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42df7ef..07acdc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ Change Log ========== -Version 3.0.2 *(2024-04-)* +Version 3.0.2 *(2024-04-15)* ---------------------------- Bugfix: diff --git a/README.md b/README.md index 1eacee9..a18b958 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ repositories { } dependencies { - implementation 'com.github.niendo1:richeditor-android:3.0.0' + implementation 'com.github.niendo1:richeditor-android:3.0.2' } ``` @@ -119,7 +119,7 @@ dependencies { com.github.niendo1 richeditor-android - 3.0.0 + 3.0.2 ``` @@ -129,7 +129,7 @@ dependencies { ```leiningen :repositories [["jitpack" "https://jitpack.io"]] -:dependencies [[com.github.niendo1/richeditor-android "3.0.0"]] +:dependencies [[com.github.niendo1/richeditor-android "3.0.2"]] ``` @@ -138,7 +138,7 @@ dependencies { ```sbt resolvers += "jitpack" at "https://jitpack.io" -libraryDependencies += "com.github.niendo1" % "richeditor-android" % "3.0.0" +libraryDependencies += "com.github.niendo1" % "richeditor-android" % "3.0.2" ``` diff --git a/gradle.properties b/gradle.properties index 28d46b1..f83b231 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.1 -VERSION_CODE=301 +VERSION_NAME=3.0.2 +VERSION_CODE=302 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=34 From a26b549e834ed88ceedc54ec8ab0a9ebc63af549 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Mon, 15 Apr 2024 18:18:47 +0200 Subject: [PATCH 129/136] "fix" applicationTests --- .../java/jp/wasabeef/richeditor/ApplicationTest.java | 9 +++------ .../java/jp/wasabeef/sample/ApplicationTest.java | 7 ++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/richeditor/src/androidTest/java/jp/wasabeef/richeditor/ApplicationTest.java b/richeditor/src/androidTest/java/jp/wasabeef/richeditor/ApplicationTest.java index 1bdd979..854f48c 100644 --- a/richeditor/src/androidTest/java/jp/wasabeef/richeditor/ApplicationTest.java +++ b/richeditor/src/androidTest/java/jp/wasabeef/richeditor/ApplicationTest.java @@ -1,14 +1,11 @@ package jp.wasabeef.richeditor; -import android.app.Application; -import android.test.ApplicationTestCase; - /** * Testing Fundamentals */ -public class ApplicationTest extends ApplicationTestCase { +public class ApplicationTest { public ApplicationTest() { - super(Application.class); + } -} \ No newline at end of file +} diff --git a/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java b/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java index 946e30d..f2bb153 100644 --- a/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java +++ b/sample/src/androidTest/java/jp/wasabeef/sample/ApplicationTest.java @@ -1,14 +1,11 @@ package jp.wasabeef.sample; -import android.app.Application; -import android.test.ApplicationTestCase; - /** * Testing Fundamentals */ -public class ApplicationTest extends ApplicationTestCase { +public class ApplicationTest { public ApplicationTest() { - super(Application.class); + } } From 0c5e649ad83381f6e176614c141b32b7988d9071 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Tue, 21 May 2024 11:52:21 +0200 Subject: [PATCH 130/136] readme update --- .idea/codeStyles/Project.xml | 2 +- README.md | 1 - richeditor/src/main/{java => javadoc}/overview.html | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) rename richeditor/src/main/{java => javadoc}/overview.html (97%) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 52792e7..0084ba7 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -388,4 +388,4 @@ - \ No newline at end of file + diff --git a/README.md b/README.md index a18b958..5c5abdf 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ Logo

    -Android Arsenal License Apache 2.0 JitPack-Lib JavaDoc diff --git a/richeditor/src/main/java/overview.html b/richeditor/src/main/javadoc/overview.html similarity index 97% rename from richeditor/src/main/java/overview.html rename to richeditor/src/main/javadoc/overview.html index 3a614e1..0d9e67a 100644 --- a/richeditor/src/main/java/overview.html +++ b/richeditor/src/main/javadoc/overview.html @@ -1,5 +1,5 @@ - + API Overview From 948de8ae10b4c54de279e02ea11c142a6973f235 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Sun, 1 Dec 2024 13:18:25 +0100 Subject: [PATCH 131/136] V3.0.3 Build/gradle updates --- build.gradle | 8 +++++++- gradle.properties | 4 ++-- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43504 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +++++-- gradlew.bat | 2 ++ sample/build.gradle | 10 ++++++++-- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 839473c..1e3f819 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,23 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. + + buildscript { + ext.kotlin_version = "2.0.20" repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } plugins { id 'maven-publish' + id 'org.jetbrains.kotlin.android' version '2.0.20' apply false + id 'org.jetbrains.kotlin.multiplatform' version '2.0.20' apply false } allprojects { diff --git a/gradle.properties b/gradle.properties index f83b231..730e96a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.2 -VERSION_CODE=302 +VERSION_NAME=3.0.3 +VERSION_CODE=303 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=34 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 8703 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 Ojj7^59?Sdh$^Qpp*~F>< delta 8662 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e7646de..e2847c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 7101f8e..9b42019 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/sample/build.gradle b/sample/build.gradle index 61080ed..91df8e1 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdk 34 + compileSdk COMPILE_SDK_VERSION as int defaultConfig { minSdkVersion MIN_SDK_VERSION as int @@ -10,6 +10,11 @@ android { versionName VERSION_NAME } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + // SigningConfigs apply from: '../signingConfigs/debug.gradle', to: android apply from: '../signingConfigs/release.gradle', to: android @@ -36,5 +41,6 @@ repositories { dependencies { implementation project(':richeditor') - implementation "androidx.appcompat:appcompat:1.6.1" + implementation "androidx.appcompat:appcompat:1.7.0" + implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.20")) } From 3e2def7589678583ed02c8c92eb3ed1b3ab41d6f Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 11 Dec 2024 08:55:51 +0100 Subject: [PATCH 132/136] Build/gradle updates --- CHANGELOG.md | 15 +++++++++++++++ build.gradle | 2 +- gradle.properties | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07acdc0..8934c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ Change Log ========== +Version 3.0.3 *(2024-12-08)* +---------------------------- + +Bugfix: + +Feature: + +Update: +- gradle-lib:8.7.3 +- gradle:8.11.1 +- appcompat:1.7.0 +- kotlin-bom:2.0.2 +- COMPILE_SDK_VERSION=35 +- TARGET_SDK_VERSION=35 + Version 3.0.2 *(2024-04-15)* ---------------------------- diff --git a/build.gradle b/build.gradle index 1e3f819..732d813 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.7.2' + classpath 'com.android.tools.build:gradle:8.7.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/gradle.properties b/gradle.properties index 730e96a..d08c582 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,8 +23,8 @@ VERSION_NAME=3.0.3 VERSION_CODE=303 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android -COMPILE_SDK_VERSION=34 -TARGET_SDK_VERSION=34 +COMPILE_SDK_VERSION=35 +TARGET_SDK_VERSION=35 MIN_SDK_VERSION=24 #android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false From e9b39729f1c32c57a9b45ec84e27a188f2b33016 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 2 May 2025 13:29:20 +0200 Subject: [PATCH 133/136] json fixes --- build.gradle | 2 +- richeditor/src/main/assets/rich_editor.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 732d813..8b7a7c1 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.7.3' + classpath 'com.android.tools.build:gradle:8.9.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 8a00c04..80b5a94 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -114,7 +114,7 @@ RE.runCallbackQueue = function() { }; RE.getCommandQueue = function() { - var commands = JSON.stringify( RE.callbackQueue ); + var commands = encodeURI(JSON.stringify( RE.callbackQueue )); RE.callbackQueue = []; return commands; }; @@ -583,7 +583,10 @@ if (element=="link" || element=="") { ret.push({"href":this.href}); ret.push({"text":this.innerHTML}); ret.push({"title":this.title}); - window.location.href = "re-click://" + JSON.stringify(ret); + var x=encodeURI(JSON.stringify(ret)); + console.log("Response value: " + x); + window.location.href = "re-click://" + encodeURI(JSON.stringify(ret)); + } ); } From 10df6fae34012951cb7fb7e80c26dd7f8f32046a Mon Sep 17 00:00:00 2001 From: niendo1 Date: Fri, 2 May 2025 22:28:46 +0200 Subject: [PATCH 134/136] Bugfix: - Layout fixes for 35 - callback not working (href needs to start with "http://) --- CHANGELOG.md | 13 ++++ gradle.properties | 4 +- richeditor/src/main/assets/rich_editor.js | 18 ++--- .../jp/wasabeef/richeditor/RichEditor.java | 69 ++++++------------- sample/src/main/res/values/styles.xml | 3 +- 5 files changed, 45 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8934c6e..0d76238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ Change Log ========== +Version 3.0.4 *(2025-05-08)* +---------------------------- + +Bugfix: +- Layout fixes for 35 +- callback not working (href needs to start with "http://) + +Feature: +- better logging + +Update: + + Version 3.0.3 *(2024-12-08)* ---------------------------- diff --git a/gradle.properties b/gradle.properties index d08c582..d6915c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true android.enableR8.fullMode=true -VERSION_NAME=3.0.3 -VERSION_CODE=303 +VERSION_NAME=3.0.4 +VERSION_CODE=304 GROUP=jp.wasabeef ARTIFACT_ID=richeditor-android COMPILE_SDK_VERSION=35 diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 80b5a94..52064a3 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -109,15 +109,12 @@ RE.runCallbackQueue = function() { } setTimeout(function() { - window.location.href = "re-callback://" + RE.getCommandQueue(); + //console.log("Response value: " + x); + window.location.href = "http://re-callback?" + encodeURI(JSON.stringify(RE.callbackQueue)); }, 0); }; -RE.getCommandQueue = function() { - var commands = encodeURI(JSON.stringify( RE.callbackQueue )); - RE.callbackQueue = []; - return commands; -}; + RE.callback = function(method) { RE.callbackQueue.push(method); @@ -583,10 +580,8 @@ if (element=="link" || element=="") { ret.push({"href":this.href}); ret.push({"text":this.innerHTML}); ret.push({"title":this.title}); - var x=encodeURI(JSON.stringify(ret)); - console.log("Response value: " + x); - window.location.href = "re-click://" + encodeURI(JSON.stringify(ret)); - + //console.log("Response value: " + x); + window.location.href = "http://re-click?" + encodeURI(JSON.stringify(ret)); } ); } @@ -895,8 +890,7 @@ RE.enabledEditingItems = function(e) { if (formatBlock.length > 0) { items.push(formatBlock); } - - window.location.href = "re-state://" + encodeURI(items.join(',')); + window.location.href = "http://re-state?" + encodeURI(JSON.stringify(items)); } RE.focus = function() { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index ec43662..c61acd8 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -1,14 +1,12 @@ package jp.wasabeef.richeditor; import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -141,9 +139,9 @@ public interface AfterInitialLoadListener { } private static final String SETUP_HTML = "file:///android_asset/rich_editor.html"; - private static final String CALLBACK_SCHEME = "re-callback://"; - private static final String STATE_SCHEME = "re-state://"; - private static final String CLICK_SCHEME= "re-click://"; + private static final String CALLBACK_SCHEME = "http://re-callback"; + private static final String STATE_SCHEME = "http://re-state"; + private static final String CLICK_SCHEME= "http://re-click"; private boolean isReady = false; private OnTextChangeListener mTextChangeListener; private onClickListener mClickListener; @@ -243,7 +241,7 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { try { unescaped = URLDecoder.decode(value, "UTF-8"); } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + Log.e("RichEditor","onReceiveValue:", e); } if (!"null".equals(unescaped)) { @@ -261,18 +259,18 @@ public void setOnInitialLoadListener(AfterInitialLoadListener listener) { private void callback(String value) { if (mTextChangeListener != null) { - mTextChangeListener.onTextChange(value.replaceFirst(CALLBACK_SCHEME, "")); + mTextChangeListener.onTextChange(value); } } private void callback_click(String value) { if (mClickListener != null) { - mClickListener.onClick(value.replaceFirst(CLICK_SCHEME, "")); + mClickListener.onClick(value); } } - private void stateCheck(String text) { - String state = text.replaceFirst(STATE_SCHEME, "").toUpperCase(Locale.ENGLISH); + private void callback_stateCheck(String text) { + String state = text.toUpperCase(Locale.ENGLISH); List types = new ArrayList<>(); for (Type type : Type.values()) { if (TextUtils.indexOf(state, type.name()) != -1) { @@ -321,11 +319,7 @@ private void applyAttributes(Context context, AttributeSet attrs) { } private void load(String trigger) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - evaluateJavascript(trigger, null); - } else { - loadUrl(trigger); - } + evaluateJavascript(trigger, null); } @@ -361,7 +355,7 @@ public void setHtml(String contents) { try { exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');"); } catch (UnsupportedEncodingException e) { - // No handling + Log.e("RichEditor","setHTML:", e); } } @@ -794,7 +788,7 @@ public void getFontFamily() { */ public void setFontSize(int fontSize) { if (fontSize > 7 || fontSize < 1) { - Log.e("RichEditor", "Font size should have a value between 1-7"); + Log.w("RichEditor", "Font size should have a value between 1-7"); } exec("javascript:RE.setFontSize('" + fontSize + "');"); } @@ -899,7 +893,7 @@ public void insertHTML(String contents) { exec("javascript:RE.prepareInsert();"); exec("javascript:RE.insertHTML('" + URLEncoder.encode(contents, "UTF-8") + "');"); } catch (UnsupportedEncodingException e) { - // No handling + Log.e("RichEditor","insertHTML", e); } } @@ -966,7 +960,7 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h try { inputStream = getContext().getContentResolver().openInputStream(imageURI); } catch (FileNotFoundException e) { - e.printStackTrace(); + Log.e("RichEditor","insertImageAsBase64 Inputstream:", e); } BitmapFactory.Options options = new BitmapFactory.Options(); @@ -975,7 +969,7 @@ public void insertImageAsBase64(Uri imageURI, String alt, String width, String h try { inputStream.close(); } catch (IOException e) { - e.printStackTrace(); + Log.e("RichEditor","insertImageAsBase64 Inputstream.close:", e); } String type = getContext().getContentResolver().getType(imageURI).toLowerCase(); String tag = "data:" + type + ";charset=utf-8;base64,"; @@ -1166,45 +1160,26 @@ public void onPageFinished(WebView view, String url) { } } - /** - * @param view The WebView that is initiating the callback. - * @param url The URL to be loaded. - * @return - */ - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - String decode = Uri.decode(url); - - if (TextUtils.indexOf(url, CALLBACK_SCHEME) == 0) { - callback(decode); - return true; - } else if (TextUtils.indexOf(url, STATE_SCHEME) == 0) { - stateCheck(decode); - return true; - } - - return super.shouldOverrideUrlLoading(view, url); - } /** * @param view The WebView that is initiating the callback. * @param request Object containing the details of the request. * @return */ - @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { final String url = request.getUrl().toString(); String decode = Uri.decode(url); - - if (TextUtils.indexOf(url, CALLBACK_SCHEME) == 0) { - callback(decode); + String list=decode.substring(decode.indexOf("?")+1); + if (decode.startsWith(CALLBACK_SCHEME)) { + callback(list); return true; - } else if (TextUtils.indexOf(url, STATE_SCHEME) == 0) { - stateCheck(decode); + } else if (decode.startsWith(STATE_SCHEME)) { + callback_stateCheck(list); return true; - } else if (TextUtils.indexOf(url, CLICK_SCHEME) == 0) { - callback_click(decode); + } else if (decode.startsWith(CLICK_SCHEME) ) { + callback_click(list); return true; } return super.shouldOverrideUrlLoading(view, request); diff --git a/sample/src/main/res/values/styles.xml b/sample/src/main/res/values/styles.xml index 1355d09..67210a9 100644 --- a/sample/src/main/res/values/styles.xml +++ b/sample/src/main/res/values/styles.xml @@ -1,8 +1,9 @@ - + From 3fd85631bd40fa7351fb62f87e9f0b4ccc9de380 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 7 May 2025 20:21:31 +0200 Subject: [PATCH 135/136] gradlelib updare --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8b7a7c1..2097e99 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.9.2' + classpath 'com.android.tools.build:gradle:8.10.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } From f50d46d489a5c7e52fdfa225f7414a3ccc772273 Mon Sep 17 00:00:00 2001 From: niendo1 Date: Wed, 7 May 2025 20:22:24 +0200 Subject: [PATCH 136/136] rework callback code make callback_stateCheck work --- CHANGELOG.md | 4 +-- richeditor/src/main/assets/rich_editor.js | 18 +++++++----- .../jp/wasabeef/richeditor/RichEditor.java | 23 ++++++++------- .../java/jp/wasabeef/sample/MainActivity.java | 28 +++++++++++++++++-- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d76238..e3ba9f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ Change Log ========== -Version 3.0.4 *(2025-05-08)* +Version 3.0.4 *(2025-05-07)* ---------------------------- Bugfix: @@ -12,7 +12,7 @@ Feature: - better logging Update: - +- gradle-lib:8.10.0 Version 3.0.3 *(2024-12-08)* ---------------------------- diff --git a/richeditor/src/main/assets/rich_editor.js b/richeditor/src/main/assets/rich_editor.js index 52064a3..f0096c4 100644 --- a/richeditor/src/main/assets/rich_editor.js +++ b/richeditor/src/main/assets/rich_editor.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2022-2024 peter@niendo.de + * Copyright (C) 2022-2025 peter@niendo.de * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2015 Wasabeef * @@ -109,8 +109,7 @@ RE.runCallbackQueue = function() { } setTimeout(function() { - //console.log("Response value: " + x); - window.location.href = "http://re-callback?" + encodeURI(JSON.stringify(RE.callbackQueue)); + RE.setCallBack("callback", RE.callbackQueue); }, 0); }; @@ -580,8 +579,7 @@ if (element=="link" || element=="") { ret.push({"href":this.href}); ret.push({"text":this.innerHTML}); ret.push({"title":this.title}); - //console.log("Response value: " + x); - window.location.href = "http://re-click?" + encodeURI(JSON.stringify(ret)); + RE.setCallBack("click", ret); } ); } @@ -890,7 +888,12 @@ RE.enabledEditingItems = function(e) { if (formatBlock.length > 0) { items.push(formatBlock); } - window.location.href = "http://re-state?" + encodeURI(JSON.stringify(items)); + RE.setCallBack("state", items); +} + +RE.setCallBack = function(schema, items) { + //console.log("Response value: " + x); + window.location.href = "http://richeditor/" + schema + "?" + encodeURI(JSON.stringify(items)); } RE.focus = function() { @@ -929,8 +932,9 @@ RE.editor.addEventListener("keyup", function(e) { RE.enabledEditingItems(e); } }); -RE.editor.addEventListener("click", RE.enabledEditingItems); */ +RE.editor.addEventListener("click", RE.enabledEditingItems); + //https://stackoverflow.com/questions/18552336/prevent-contenteditable-adding-div-on-enter-chrome RE.editor.addEventListener("keydown", function(e) { diff --git a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java index c61acd8..ff26012 100644 --- a/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java +++ b/richeditor/src/main/java/jp/wasabeef/richeditor/RichEditor.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** - * Copyright (C) 2022-2024 niendo + * Copyright (C) 2022-2025 niendo * Copyright (C) 2017 Kishan Jadav * Copyright (C) 2020 Wasabeef *

    @@ -139,9 +139,9 @@ public interface AfterInitialLoadListener { } private static final String SETUP_HTML = "file:///android_asset/rich_editor.html"; - private static final String CALLBACK_SCHEME = "http://re-callback"; - private static final String STATE_SCHEME = "http://re-state"; - private static final String CLICK_SCHEME= "http://re-click"; + private static final String CALLBACK_SCHEME = "http://richeditor/callback"; + private static final String STATE_SCHEME = "http://richeditor/state"; + private static final String CLICK_SCHEME= "http://richeditor/click"; private boolean isReady = false; private OnTextChangeListener mTextChangeListener; private onClickListener mClickListener; @@ -270,15 +270,14 @@ private void callback_click(String value) { } private void callback_stateCheck(String text) { - String state = text.toUpperCase(Locale.ENGLISH); - List types = new ArrayList<>(); - for (Type type : Type.values()) { - if (TextUtils.indexOf(state, type.name()) != -1) { - types.add(type); - } - } - if (mDecorationStateListener != null) { + String state = text.toUpperCase(Locale.ENGLISH); + List types = new ArrayList<>(); + for (Type type : Type.values()) { + if (TextUtils.indexOf(state, type.name()) != -1) { + types.add(type); + } + } mDecorationStateListener.onStateChangeListener(state, types); } } diff --git a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java index 7263d51..9a12cae 100644 --- a/sample/src/main/java/jp/wasabeef/sample/MainActivity.java +++ b/sample/src/main/java/jp/wasabeef/sample/MainActivity.java @@ -9,6 +9,24 @@ import jp.wasabeef.richeditor.RichEditor; +/** + * Copyright (C) 2022-2025 niendo + * Copyright (C) 2017 Kishan Jadav + * Copyright (C) 2020 Wasabeef + *

    + * 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. + */ + public class MainActivity extends AppCompatActivity { private RichEditor mEditor; @@ -18,7 +36,7 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - mEditor = (RichEditor) findViewById(R.id.editor); + mEditor = findViewById(R.id.editor); mEditor.setEditorHeight(200); mEditor.setEditorFontSize(22); mEditor.setEditorFontColor(Color.RED); @@ -30,7 +48,7 @@ protected void onCreate(Bundle savedInstanceState) { mEditor.setPlaceholder("Insert text here..."); //mEditor.setInputEnabled(false); mEditor.LoadFont("Alita Brush","Alita Brush.ttf"); - mPreview = (TextView) findViewById(R.id.preview); + mPreview = findViewById(R.id.preview); mEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() { @Override @@ -42,6 +60,12 @@ public void onTextChange(String text) { } }); + // mEditor.setOnDecorationChangeListener(new RichEditor.OnDecorationStateListener() { + // @Override public void onStateChangeListener(String text, List types) { + // + // } + // }); + findViewById(R.id.action_undo).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {