songweig radames HF staff commited on
Commit
baa687a
1 Parent(s): 5db5f99

rich-text-iframe (#4)

Browse files

- embed editor into an iframe (fd5c689482083d43cd760ce82ca65de758a38e18)
- change layout (373e9834353ad82d8c1ba4c7e81eff20264f06ad)


Co-authored-by: Radamés Ajna <radames@users.noreply.huggingface.co>

Files changed (3) hide show
  1. README.md +1 -1
  2. app.py +6 -16
  3. rich-text-to-json-iframe.html +270 -0
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🌍
4
  colorFrom: indigo
5
  colorTo: pink
6
  sdk: gradio
7
- sdk_version: 3.23.0
8
  app_file: app.py
9
  pinned: false
10
  ---
 
4
  colorFrom: indigo
5
  colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 3.27.0
8
  app_file: app.py
9
  pinned: false
10
  ---
app.py CHANGED
@@ -26,21 +26,12 @@ If you are encountering an error or not achieving your desired outcome, here are
26
  4. Consider using a different seed.
27
  """
28
 
29
- canvas_html = """<rich-text-editor id="rich-text-root"></rich-text-editor>"""
30
- load_js = """
31
- async () => {
32
- const scripts = ["https://cdn.quilljs.com/1.3.6/quill.min.js","file=rich-text-to-json.js"]
33
- scripts.forEach(src => {
34
- const script = document.createElement('script');
35
- script.src = src;
36
- document.head.appendChild(script);
37
- })
38
- }
39
- """
40
  get_js_data = """
41
  async (text_input, negative_prompt, height, width, seed, steps, guidance_weight, color_guidance_weight, rich_text_input) => {
42
  const richEl = document.getElementById("rich-text-root");
43
- const data = richEl? richEl._data : {};
44
  return [text_input, negative_prompt, height, width, seed, steps, guidance_weight, color_guidance_weight, JSON.stringify(data)];
45
  }
46
  """
@@ -121,13 +112,12 @@ def main():
121
  return [plain_img[0], rich_img[0], token_maps]
122
 
123
  with gr.Blocks() as demo:
124
- # demo.load(None, None, None, _js=load_js)
125
  gr.HTML("""<h1 style="font-weight: 900; margin-bottom: 7px;">Expressive Text-to-Image Generation with Rich Text</h1>
126
  <p> Visit our <a href="https://rich-text-to-image.github.io/rich-text-to-json.html">rich-text-to-json interface</a> to generate rich-text JSON input.<p/>
127
  <p> <a href="https://rich-text-to-image.github.io">[Website]</a> | <a href="https://github.com/SongweiGe/rich-text-to-image">[Code]</a> <p/> """)
128
  with gr.Row():
129
  with gr.Column():
130
- rich_text_el = gr.HTML(canvas_html,elem_id="canvas_html")
131
  rich_text_input = gr.Textbox(value="", visible=False)
132
  text_input = gr.Textbox(
133
  label='Rich-text JSON Input',
@@ -172,10 +162,10 @@ def main():
172
  generate_button = gr.Button("Generate")
173
 
174
  with gr.Column():
 
175
  with gr.Row():
176
  plaintext_result = gr.Image(label='Plain-text')
177
- richtext_result = gr.Image(label='Rich-text')
178
- token_map = gr.Image(label='Token Maps')
179
 
180
  with gr.Row():
181
  gr.Markdown(help_text)
 
26
  4. Consider using a different seed.
27
  """
28
 
29
+
30
+ canvas_html = """<iframe id='rich-text-root' style='width:100%' height='360px' src='file=rich-text-to-json-iframe.html' frameborder='0' scrolling='no'></iframe>"""
 
 
 
 
 
 
 
 
 
31
  get_js_data = """
32
  async (text_input, negative_prompt, height, width, seed, steps, guidance_weight, color_guidance_weight, rich_text_input) => {
33
  const richEl = document.getElementById("rich-text-root");
34
+ const data = richEl? richEl.contentDocument.body._data : {};
35
  return [text_input, negative_prompt, height, width, seed, steps, guidance_weight, color_guidance_weight, JSON.stringify(data)];
36
  }
37
  """
 
112
  return [plain_img[0], rich_img[0], token_maps]
113
 
114
  with gr.Blocks() as demo:
 
115
  gr.HTML("""<h1 style="font-weight: 900; margin-bottom: 7px;">Expressive Text-to-Image Generation with Rich Text</h1>
116
  <p> Visit our <a href="https://rich-text-to-image.github.io/rich-text-to-json.html">rich-text-to-json interface</a> to generate rich-text JSON input.<p/>
117
  <p> <a href="https://rich-text-to-image.github.io">[Website]</a> | <a href="https://github.com/SongweiGe/rich-text-to-image">[Code]</a> <p/> """)
118
  with gr.Row():
119
  with gr.Column():
120
+ rich_text_el = gr.HTML(canvas_html, elem_id="canvas_html")
121
  rich_text_input = gr.Textbox(value="", visible=False)
122
  text_input = gr.Textbox(
123
  label='Rich-text JSON Input',
 
162
  generate_button = gr.Button("Generate")
163
 
164
  with gr.Column():
165
+ richtext_result = gr.Image(label='Rich-text')
166
  with gr.Row():
167
  plaintext_result = gr.Image(label='Plain-text')
168
+ token_map = gr.Image(label='Token Maps')
 
169
 
170
  with gr.Row():
171
  gr.Markdown(help_text)
rich-text-to-json-iframe.html ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <title>Rich Text to JSON</title>
6
+ <link rel="stylesheet" href="https://cdn.quilljs.com/1.3.6/quill.snow.css">
7
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
8
+ <link rel="stylesheet"
9
+ href='https://fonts.googleapis.com/css?family=Mirza|Roboto|Slabo+27px|Sofia|Inconsolata|Ubuntu|Akronim|Monoton&display=swap'>
10
+ <style>
11
+ html,
12
+ body {
13
+ background-color: white;
14
+ margin: 0;
15
+ }
16
+
17
+ /* Set default font-family */
18
+ .ql-snow .ql-tooltip::before {
19
+ content: "Footnote";
20
+ line-height: 26px;
21
+ margin-right: 8px;
22
+ }
23
+
24
+ .ql-snow .ql-tooltip[data-mode=link]::before {
25
+ content: "Enter footnote:";
26
+ }
27
+
28
+ .row {
29
+ margin-top: 15px;
30
+ margin-left: 0px;
31
+ margin-bottom: 15px;
32
+ }
33
+
34
+ .btn-primary {
35
+ color: #ffffff;
36
+ background-color: #2780e3;
37
+ border-color: #2780e3;
38
+ }
39
+
40
+ .btn-primary:hover {
41
+ color: #ffffff;
42
+ background-color: #1967be;
43
+ border-color: #1862b5;
44
+ }
45
+
46
+ .btn {
47
+ display: inline-block;
48
+ margin-bottom: 0;
49
+ font-weight: normal;
50
+ text-align: center;
51
+ vertical-align: middle;
52
+ touch-action: manipulation;
53
+ cursor: pointer;
54
+ background-image: none;
55
+ border: 1px solid transparent;
56
+ white-space: nowrap;
57
+ padding: 10px 18px;
58
+ font-size: 15px;
59
+ line-height: 1.42857143;
60
+ border-radius: 0;
61
+ user-select: none;
62
+ }
63
+
64
+ #standalone-container {
65
+ width: 100%;
66
+ background-color: #ffffff;
67
+ }
68
+
69
+ #editor-container {
70
+ font-family: "Aref Ruqaa";
71
+ font-size: 18px;
72
+ height: 250px;
73
+ width: 100%;
74
+ }
75
+
76
+ #toolbar-container {
77
+ font-family: "Aref Ruqaa";
78
+ display: flex;
79
+ flex-wrap: wrap;
80
+ }
81
+
82
+ #json-container {
83
+ max-width: 720px;
84
+ }
85
+
86
+ /* Set dropdown font-families */
87
+ #toolbar-container .ql-font span[data-label="Base"]::before {
88
+ font-family: "Aref Ruqaa";
89
+ }
90
+
91
+ #toolbar-container .ql-font span[data-label="Claude Monet"]::before {
92
+ font-family: "Mirza";
93
+ }
94
+
95
+ #toolbar-container .ql-font span[data-label="Ukiyoe"]::before {
96
+ font-family: "Roboto";
97
+ }
98
+
99
+ #toolbar-container .ql-font span[data-label="Cyber Punk"]::before {
100
+ font-family: "Comic Sans MS";
101
+ }
102
+
103
+ #toolbar-container .ql-font span[data-label="Pop Art"]::before {
104
+ font-family: "sofia";
105
+ }
106
+
107
+ #toolbar-container .ql-font span[data-label="Van Gogh"]::before {
108
+ font-family: "slabo 27px";
109
+ }
110
+
111
+ #toolbar-container .ql-font span[data-label="Pixel Art"]::before {
112
+ font-family: "inconsolata";
113
+ }
114
+
115
+ #toolbar-container .ql-font span[data-label="Rembrandt"]::before {
116
+ font-family: "ubuntu";
117
+ }
118
+
119
+ #toolbar-container .ql-font span[data-label="Cubism"]::before {
120
+ font-family: "Akronim";
121
+ }
122
+
123
+ #toolbar-container .ql-font span[data-label="Neon Art"]::before {
124
+ font-family: "Monoton";
125
+ }
126
+
127
+ /* Set content font-families */
128
+ .ql-font-mirza {
129
+ font-family: "Mirza";
130
+ }
131
+
132
+ .ql-font-roboto {
133
+ font-family: "Roboto";
134
+ }
135
+
136
+ .ql-font-cursive {
137
+ font-family: "Comic Sans MS";
138
+ }
139
+
140
+ .ql-font-sofia {
141
+ font-family: "sofia";
142
+ }
143
+
144
+ .ql-font-slabo {
145
+ font-family: "slabo 27px";
146
+ }
147
+
148
+ .ql-font-inconsolata {
149
+ font-family: "inconsolata";
150
+ }
151
+
152
+ .ql-font-ubuntu {
153
+ font-family: "ubuntu";
154
+ }
155
+
156
+ .ql-font-Akronim {
157
+ font-family: "Akronim";
158
+ }
159
+
160
+ .ql-font-Monoton {
161
+ font-family: "Monoton";
162
+ }
163
+ </style>
164
+ </head>
165
+
166
+ <body>
167
+ <div id="standalone-container">
168
+ <div id="toolbar-container">
169
+ <span class="ql-formats">
170
+ <select class="ql-font">
171
+ <option selected>Base</option>
172
+ <option value="mirza">Claude Monet</option>
173
+ <option value="roboto">Ukiyoe</option>
174
+ <option value="cursive">Cyber Punk</option>
175
+ <option value="sofia">Pop Art</option>
176
+ <option value="slabo">Van Gogh</option>
177
+ <option value="inconsolata">Pixel Art</option>
178
+ <option value="ubuntu">Rembrandt</option>
179
+ <option value="Akronim">Cubism</option>
180
+ <option value="Monoton">Neon Art</option>
181
+ </select>
182
+ <select class="ql-size">
183
+ <option value="18px">Small</option>
184
+ <option selected>Normal</option>
185
+ <option value="32px">Large</option>
186
+ <option value="50px">Huge</option>
187
+ </select>
188
+ </span>
189
+ <span class="ql-formats">
190
+ <button class="ql-strike"></button>
191
+ </span>
192
+ <!-- <span class="ql-formats">
193
+ <button class="ql-bold"></button>
194
+ <button class="ql-italic"></button>
195
+ <button class="ql-underline"></button>
196
+ </span> -->
197
+ <span class="ql-formats">
198
+ <select class="ql-color"></select>
199
+ <!-- <select class="ql-background"></select> -->
200
+ </span>
201
+ <!-- <span class="ql-formats">
202
+ <button class="ql-script" value="sub"></button>
203
+ <button class="ql-script" value="super"></button>
204
+ </span>
205
+ <span class="ql-formats">
206
+ <button class="ql-header" value="1"></button>
207
+ <button class="ql-header" value="2"></button>
208
+ <button class="ql-blockquote"></button>
209
+ <button class="ql-code-block"></button>
210
+ </span>
211
+ <span class="ql-formats">
212
+ <button class="ql-list" value="ordered"></button>
213
+ <button class="ql-list" value="bullet"></button>
214
+ <button class="ql-indent" value="-1"></button>
215
+ <button class="ql-indent" value="+1"></button>
216
+ </span>
217
+ <span class="ql-formats">
218
+ <button class="ql-direction" value="rtl"></button>
219
+ <select class="ql-align"></select>
220
+ </span>
221
+ <span class="ql-formats">
222
+ <button class="ql-link"></button>
223
+ <button class="ql-image"></button>
224
+ <button class="ql-video"></button>
225
+ <button class="ql-formula"></button>
226
+ </span> -->
227
+ <span class="ql-formats">
228
+ <button class="ql-link"></button>
229
+ </span>
230
+ <span class="ql-formats">
231
+ <button class="ql-clean"></button>
232
+ </span>
233
+ </div>
234
+ <div id="editor-container" style="height:300px;"></div>
235
+ </div>
236
+ <script src="https://cdn.quilljs.com/1.3.6/quill.min.js"></script>
237
+ <script>
238
+
239
+ // Register the customs format with Quill
240
+ const Font = Quill.import('formats/font');
241
+ Font.whitelist = ['mirza', 'roboto', 'sofia', 'slabo', 'inconsolata', 'ubuntu', 'cursive', 'Akronim', 'Monoton'];
242
+ const Link = Quill.import('formats/link');
243
+ Link.sanitize = function (url) {
244
+ // modify url if desired
245
+ return url;
246
+ }
247
+ const SizeStyle = Quill.import('attributors/style/size');
248
+ SizeStyle.whitelist = ['10px', '18px', '32px', '50px', '64px'];
249
+ Quill.register(SizeStyle, true);
250
+ Quill.register(Link, true);
251
+ Quill.register(Font, true);
252
+ const icons = Quill.import('ui/icons');
253
+ icons['link'] = `<svg xmlns="http://www.w3.org/2000/svg" width="17" viewBox="0 0 512 512" xml:space="preserve"><path fill="#010101" d="M276.75 1c4.51 3.23 9.2 6.04 12.97 9.77 29.7 29.45 59.15 59.14 88.85 88.6 4.98 4.93 7.13 10.37 7.12 17.32-.1 125.8-.09 251.6-.01 377.4 0 7.94-1.96 14.46-9.62 18.57-121.41.34-242.77.34-364.76.05A288.3 288.3 0 0 1 1 502c0-163.02 0-326.04.34-489.62C3.84 6.53 8.04 3.38 13 1c23.35 0 46.7 0 70.82.3 2.07.43 3.38.68 4.69.68h127.98c18.44.01 36.41.04 54.39-.03 1.7 0 3.41-.62 5.12-.95h.75M33.03 122.5v359.05h320.22V129.18h-76.18c-14.22-.01-19.8-5.68-19.8-20.09V33.31H33.02v89.19m256.29-27.36c.72.66 1.44 1.9 2.17 1.9 12.73.12 25.46.08 37.55.08L289.3 57.45v37.7z"/><path fill="#020202" d="M513 375.53c-4.68 7.99-11.52 10.51-20.21 10.25-13.15-.4-26.32-.1-39.48-.1h-5.58c5.49 8.28 10.7 15.74 15.46 23.47 6.06 9.82 1.14 21.65-9.96 24.27-6.7 1.59-12.45-.64-16.23-6.15a2608.6 2608.6 0 0 1-32.97-49.36c-3.57-5.48-3.39-11.54.17-16.98a3122.5 3122.5 0 0 1 32.39-48.56c5.22-7.65 14.67-9.35 21.95-4.45 7.63 5.12 9.6 14.26 4.5 22.33-4.75 7.54-9.8 14.9-15.11 22.95h33.64V225.19h-5.24c-19.49 0-38.97.11-58.46-.05-12.74-.1-20.12-13.15-13.84-24.14 3.12-5.46 8.14-7.71 14.18-7.73 26.15-.06 52.3-.04 78.45 0 7.1 0 12.47 3.05 16.01 9.64.33 57.44.33 114.8.33 172.62z"/><path fill="#111" d="M216.03 1.97C173.52 1.98 131 2 88.5 1.98a16 16 0 0 1-4.22-.68c43.4-.3 87.09-.3 131.24-.06.48.25.5.73.5.73z"/><path fill="#232323" d="M216.5 1.98c-.47 0-.5-.5-.5-.74C235.7 1 255.38 1 275.53 1c-1.24.33-2.94.95-4.65.95-17.98.07-35.95.04-54.39.03z"/><path fill="#040404" d="M148 321.42h153.5c14.25 0 19.96 5.71 19.96 19.97.01 19.17.03 38.33 0 57.5-.03 12.6-6.16 18.78-18.66 18.78H99.81c-12.42 0-18.75-6.34-18.76-18.73-.01-19.83-.02-39.66 0-59.5.02-11.47 6.4-17.93 17.95-18 16.17-.08 32.33-.02 49-.02m40.5 32.15h-75.16v31.84h175.7v-31.84H188.5z"/><path fill="#030303" d="m110 225.33 178.89-.03c11.98 0 19.25 9.95 15.74 21.44-2.05 6.71-7.5 10.57-15.14 10.57-63.63 0-127.25-.01-190.88-.07-12.03-.02-19.17-8.62-16.7-19.84 1.6-7.21 7.17-11.74 15.1-12.04 4.17-.16 8.33-.03 13-.03zm-24.12-36.19c-5.28-6.2-6.3-12.76-2.85-19.73 3.22-6.49 9.13-8.24 15.86-8.24 25.64.01 51.27-.06 76.91.04 13.07.04 20.66 10.44 16.33 22.08-2.25 6.06-6.63 9.76-13.08 9.8-27.97.18-55.94.2-83.9-.07-3.01-.03-6-2.36-9.27-3.88z"/></svg>`
254
+ const quill = new Quill('#editor-container', {
255
+ modules: {
256
+ toolbar: {
257
+ container: '#toolbar-container',
258
+ },
259
+ },
260
+ theme: 'snow'
261
+ });
262
+
263
+ quill.on('text-change', () => {
264
+ // keep qull data inside _data to communicate with Gradio
265
+ document.body._data = quill.getContents()
266
+ })
267
+ </script>
268
+ </body>
269
+
270
+ </html>