Skip to content

Commit 2a5797c

Browse files
committed
refactor: cleanup
1 parent 621c1e1 commit 2a5797c

3 files changed

Lines changed: 61 additions & 52 deletions

File tree

apps/example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,7 +2026,7 @@ EXTERNAL SOURCES:
20262026

20272027
SPEC CHECKSUMS:
20282028
FBLazyVector: c00c20551d40126351a6783c47ce75f5b374851b
2029-
hermes-engine: d80056af9dcb5ba3db80f37943f96751037c7381
2029+
hermes-engine: b4dad6ba67535bb03c8ff1006b337cba14db16cb
20302030
RCTDeprecation: 3bb167081b134461cfeb875ff7ae1945f8635257
20312031
RCTRequired: 74839f55d5058a133a0bc4569b0afec750957f64
20322032
RCTSwiftUI: 87a316382f3eab4dd13d2a0d0fd2adcce917361a
@@ -2035,7 +2035,7 @@ SPEC CHECKSUMS:
20352035
React: 1b1536b9099195944034e65b1830f463caaa8390
20362036
React-callinvoker: 6dff6d17d1d6cc8fdf85468a649bafed473c65f5
20372037
React-Core: 39ee05b5798296f433dd3c3624c57a187c1510e3
2038-
React-Core-prebuilt: ff86a9cfffdf1ac6deca527352be5e6d0290354a
2038+
React-Core-prebuilt: 69556f895326f23c007f3a6869340045d7dca106
20392039
React-CoreModules: e78bfd2617075bc0e50c689df4a29232bd72ad82
20402040
React-cxxreact: 3fe21801d46097cf74c3dff6953677bebc4a3c2a
20412041
React-debug: e1f00fcd2cef58a2897471a6d76a4ef5f5f90c74
@@ -2097,7 +2097,7 @@ SPEC CHECKSUMS:
20972097
ReactAppDependencyProvider: 706b65371b90b5cc797b6639e8979f2e5cecd6da
20982098
ReactCodegen: ab01ebfffac5cda9140204eb872ed97c15df225f
20992099
ReactCommon: 47ef95b0920948a0b54d7439f7452501eeeac071
2100-
ReactNativeDependencies: 6e31d9f8b60229e795cddfbb4d99db3858730bbf
2100+
ReactNativeDependencies: 8a208df374583424130645685d86306befc275cf
21012101
ReactNativeEnrichedHtml: 7d90df4aced7f533c7bd15ac296879b214413361
21022102
Yoga: e83c3121d079541e69f3c5c623faaaf933fb5812
21032103

cpp/parser/GumboNormalizer.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,34 @@ static void emit_one_attr(buffer_t *out, GumboElement *el,
411411
}
412412
}
413413

414+
static bool is_checkbox_list(GumboElement *el) {
415+
const char *val = get_attr(el, "data-type");
416+
if (val && (strcmp(val, "checkbox") == 0 || strcmp(val, "checkboxList") == 0)) {
417+
return true;
418+
}
419+
420+
// In Google Docs and MS Word the <li> elements define if it is a checkbox
421+
// list. We only need to check the first <li>.
422+
GumboVector *children = &el->children;
423+
for (unsigned int i = 0; i < children->length; i++) {
424+
GumboNode *child = children->data[i];
425+
if (is_element(child)) {
426+
char child_tag[64];
427+
if (get_tag_name(child, child_tag, sizeof(child_tag)) && strcmp(child_tag, "li") == 0) {
428+
GumboElement *child_el = &child->v.element;
429+
const char *role = get_attr(child_el, "role");
430+
const char *cls = get_attr(child_el, "class");
431+
432+
// Matches Google Docs (role="checkbox") OR MS Word (class includes "checklist")
433+
return (role && strcmp(role, "checkbox") == 0) ||
434+
(cls && strstr(cls, "checklist") != NULL);
435+
}
436+
}
437+
}
438+
439+
return false;
440+
}
441+
414442
static void emit_attributes(GumboElement *el, const char *tag_name,
415443
buffer_t *out) {
416444
if (strcmp(tag_name, "a") == 0) {
@@ -421,33 +449,7 @@ static void emit_attributes(GumboElement *el, const char *tag_name,
421449
emit_one_attr(out, el, "width");
422450
emit_one_attr(out, el, "height");
423451
} else if (strcmp(tag_name, "ul") == 0) {
424-
425-
const char *val = get_attr(el, "data-type");
426-
bool is_checkbox = (val && (strcmp(val, "checkbox") == 0 || strcmp(val, "checkboxList") == 0));
427-
428-
// In Google Docs and MS Word the <li> elements define if it is a checkbox list
429-
if (!is_checkbox) {
430-
GumboVector *children = &el->children;
431-
for (unsigned int i = 0; i < children->length; i++) {
432-
GumboNode *child = children->data[i];
433-
if (is_element(child)) {
434-
char child_tag[64];
435-
if (get_tag_name(child, child_tag, sizeof(child_tag)) && strcmp(child_tag, "li") == 0) {
436-
GumboElement *child_el = &child->v.element;
437-
const char *role = get_attr(child_el, "role");
438-
const char *cls = get_attr(child_el, "class");
439-
440-
if ((role && strcmp(role, "checkbox") == 0) ||
441-
(cls && strstr(cls, "checklist") != NULL)) {
442-
is_checkbox = true;
443-
}
444-
break; // We only need to check the first <li>
445-
}
446-
}
447-
}
448-
}
449-
450-
if (is_checkbox) {
452+
if (is_checkbox_list(el)) {
451453
buffer_append_str(out, " data-type=\"checkbox\"");
452454
}
453455
} else if (strcmp(tag_name, "li") == 0) {

src/web/normalization/htmlNormalizer.ts

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -249,29 +249,10 @@ function emitAttributes(el: Element, name: string): string {
249249
emitOneAttr(el, 'width') +
250250
emitOneAttr(el, 'height')
251251
);
252-
case 'ul': {
253-
let isCheckbox =
254-
el.getAttribute('data-type') === 'checkbox' ||
255-
el.getAttribute('data-type') === 'checkboxList';
256-
257-
if (!isCheckbox) {
258-
const firstLi = Array.from(el.children).find(
259-
(c) => c.tagName.toLowerCase() === 'li'
260-
);
261-
if (firstLi) {
262-
const role = firstLi.getAttribute('role');
263-
const className = firstLi.getAttribute('class') || '';
264-
265-
// Matches Google Docs (role="checkbox") OR MS Word (class includes "checklist")
266-
if (role === 'checkbox' || className.includes('checklist')) {
267-
isCheckbox = true;
268-
}
269-
}
270-
}
271-
272-
return isCheckbox ? ' data-type="checkbox"' : '';
273-
}
252+
case 'ul':
253+
return isCheckboxList(el) ? ' data-type="checkbox"' : '';
274254
case 'li':
255+
// "" is the UTF-8 hex encoding for U+F0FE (MS Word Checked Box)
275256
const isChecked =
276257
el.hasAttribute('checked') ||
277258
el.getAttribute('data-checked') === 'true' ||
@@ -289,6 +270,32 @@ function emitAttributes(el: Element, name: string): string {
289270
}
290271
}
291272

273+
function isCheckboxList(el: Element): boolean {
274+
if (
275+
el.getAttribute('data-type') === 'checkbox' ||
276+
el.getAttribute('data-type') === 'checkboxList'
277+
) {
278+
return true;
279+
}
280+
281+
// In Google Docs and MS Word the <li> elements define if it is a checkbox
282+
// list. We only need to check the first <li>.
283+
const firstLi = Array.from(el.children).find(
284+
(c) => c.tagName.toLowerCase() === 'li'
285+
);
286+
if (firstLi) {
287+
const role = firstLi.getAttribute('role');
288+
const className = firstLi.getAttribute('class') || '';
289+
290+
// Matches Google Docs (role="checkbox") OR MS Word (class includes "checklist")
291+
if (role === 'checkbox' || className.includes('checklist')) {
292+
return true;
293+
}
294+
}
295+
296+
return false;
297+
}
298+
292299
function isGoogleDocsWrapper(el: Element, tag: string): boolean {
293300
if (tag !== 'b') return false;
294301
const id = el.getAttribute('id');

0 commit comments

Comments
 (0)