Skip to content

Sync master from upstream - #116

Merged
vanshk141999 merged 59 commits into
masterfrom
sync/master-20260709
Jul 9, 2026
Merged

vanshk141999 merged 59 commits into
masterfrom
sync/master-20260709

Conversation

@vanshk141999

Copy link
Copy Markdown
Collaborator

Syncs private master into the public mirror.

  • Upstream range: fcc449adf0da71181eacb12aaaf56251eb4d700b..5256246b399b3801dc85b29d521b888fca9ed2b6
  • New commits on the mirror: 58 (57 upstream + 1 strip commit)
  • Strip applied: yes — internal-only paths removed in a single commit (.claude/, docs/, internal-docs/, nested CLAUDE.md files, internal workflows, bin/ release scripts)
  • The branch is capped with a merge commit whose first parent is master on this repo, so the diff below shows only real upstream changes — no internal-file deletions appear.

Highlights

  • Dashboard AI quick draft flow with analytics tracking (#2915)
  • Email field: enforce RFC 5321 length limits with filter (#2911, #2904)
  • Entries: pass per-log retry metadata through the logs REST response (#2898)
  • Payments: pin one-time Stripe intent payload to card (#2916)
  • Payments: exclude repeater children from field mappers; support fields nested in containers (#2918)
  • Fix: dispatch srfm_form_reset event and reset Dropdown on form reset (#2912)
  • Fix: page break settings shared component (#2914)
  • Fix: restore bullet/ordered list visibility in react-quill editor and frontend confirmation message (#2909 area)
  • React 19 readiness: import createRoot from @wordpress/element instead of react-dom (#2909)
  • Version bump 2.12.1 + changelog, release date 8th July 2026
  • Chore: update BSF Analytics library to 1.1.29 (#2924)
  • CI: pin WP-CLI to v2.12.0 in update-translations; use npm ci in deploy/asset workflows (#2928, #2929)
  • i18n: update translations (#2927)

vanshk141999 and others added 30 commits June 23, 2026 17:09
…onse

The entry activity-log REST endpoint whitelisted only id/title/timestamp/messages.
Pass through a sanitized 'retry' => { type, id } field when present on a log row,
so the Pro entries UI can render a per-row Retry button for a specific failed
webhook / native integration. No behavior change when the key is absent.
…ct-dom (React 19 readiness)

Three single-form-settings modules imported `createRoot` directly from
`react-dom/client`. While the build externalizes it to the WP-provided
ReactDOM global (no react-dom runtime is bundled), the direct react-dom/client
import is the fragile, non-preferred path under React 19 — Gutenberg/WP will
move React + react-dom to v19, and code should always go through the
WP-supplied runtime via @wordpress/element.

Switch the three call sites to `import { createRoot } from '@wordpress/element'`
(drop-in; identical createRoot().render() API, resolves to wp.element at
runtime) and declare @wordpress/element in package.json.

- src/admin/single-form-settings/InstantForm.js
- src/admin/single-form-settings/components/SRFMEditorHeader.js
- src/admin/single-form-settings/components/useSubmitButton.js

No bundled react-dom runtime before or after (verified). SureForms Pro is
unaffected — it already mounts exclusively via @wordpress/element.
Fourth and final react-dom/client import in the plugin (this one lives under
modules/, outside the earlier src/ sweep). Same React-19-readiness change:
route createRoot through @wordpress/element (wp.element) instead of
react-dom/client, so it always uses the WP-provided runtime.

The quickActionSidebar bundle now externalizes wp-element instead of
react-dom, with no react-dom runtime bundled (verified).
…O.md)

The strip loop matched only the root CLAUDE.md, so nested CLAUDE.md files
(inc/abilities/, tests/play/specs/) and the docs/ tree leaked into the
public mirror PR diff. Strip all CLAUDE.md at any depth via git ls-files,
add docs/ and tests/play/specs/TODO.md to the list, and add a markdown
sanity check (README.md is the only expected public doc).
Cap the Email field's local part at 64 and domain at 255 chars (split on the
last @), overridable via the `srfm_email_field_char_limits` filter. Prevents
DB bloat from oversized email submissions while staying customizable.

- Server-side (authoritative): validate_form_data() in inc/field-validation.php,
  mirroring the textarea min-length block. Only the main value is submitted (the
  confirm input has no `name`), so the server validates that; the confirm is
  enforced client-side and must match the main value.
- Client-side (UX): assets/js/unminified/validation.js email block validates the
  main and confirm inputs pre-submit, showing the same message.
- New translatable message `srfm_email_char_limit` registered in
  Translatable::dynamic_messages()/dynamic_messages_source() and added to the
  global-settings allowlists so it's editable from the admin.

Closes #2904
The email field's `.srfm-error-message` is hidden by default and only shown via
an explicit inline display:block (as the format-error and confirm-mismatch
handlers already do). The char-limit error set the message text + red border but
not display:block, so a too-long email showed the border with no message.

- Submit path: set `display = 'block'` on the main and confirm error elements
  when flagging an over-length email.
- Blur handler: also flag a valid-format-but-too-long value live (mirroring the
  format error), showing the length-specific message.
Replace the single generic "Please enter a shorter email address." with two
parameterized messages, so the user knows which part is too long and the cap:

- srfm_email_local_max_length:  "The part before @ may not exceed %s characters."
- srfm_email_domain_max_length: "The part after @ may not exceed %s characters."

Server (field-validation.php) picks the local or domain message and sprintf()s
the relevant limit; client (validation.js) does the same via srfmSprintfString
in the submit + blur paths. Registered in both translatable arrays and both
global-settings allowlists (replacing srfm_email_char_limit).
Addresses Om's (osk02) review on #2910:
- Step 5 markdown sanity check now aborts the sync (exit 1) instead of
  only warning, so a detected leak halts the publish. Runs in the temp
  worktree before any push, so nothing internal reaches the mirror.
- Fix the inc/lib/ allowlist branch ('inc/lib/.*' not 'inc/lib/') so the
  third-party readmes don't trip the now-enforcing check on every sync.
- Strip nested CLAUDE.md without a pipe-to-while subshell so a failing
  git rm surfaces instead of being swallowed.
- Drop the redundant 'CLAUDE.md' literal ('*CLAUDE.md' matches root too).
The native form.reset() only resets standard HTML elements. Custom
JS-controlled fields (TomSelect dropdown, date/time pickers, signature
pads, sliders, file upload, rating) were left in their previous state
after a "Reset Form" submission action.

- Dispatch a new `srfm_form_reset` CustomEvent (with `form` in detail)
  immediately after `form.reset()` in `showSuccessMessage()`.
- Add a `srfm_form_reset` listener in dropdown.js that calls
  `tomInputInstance.clear()` and clears the companion hidden input for
  every TomSelect dropdown inside the submitted form.

Pro fields (Date, Time, Slider, Upload, Rating, Signature) will handle
the same event in sureforms-pro.

Fixes #2530

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The vendor quill.snow.css (Quill 2.x) renders bullet markers via
.ql-ui::before child elements, but react-quill bundles Quill 1.3.7
which uses ul>li::before pseudo-elements. This mismatch made bullets
invisible in all admin react-quill contexts.

Fix by adding Quill 1.x-compatible li::before rules:
- Via wp_add_inline_style() on the reactQuill handle for both the
  form editor page and the global settings page (sidebar QuillEditor)
- Via the srfm-textarea-quill-styles SASS mixin for the block editor
  canvas textarea block preview

Fixes #2149

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Quill 1.x (react-quill) uses CSS counters on ol li::before for numbered
lists, but the vendor quill.snow.css (Quill 2.x) uses .ql-ui child
elements — leaving ordered lists without numbers in the admin editor.

Add the full set of Quill 1.x counter rules (list-0 through list-9,
decimal → lower-alpha → lower-roman per indent level) via:
- wp_add_inline_style() on the reactQuill handle (form editor + settings)
- srfm-textarea-quill-styles SASS mixin (block editor canvas)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two separate frontend issues were caused by the Quill 1.x vs 2.x CSS mismatch:

1. Confirmation message (static HTML in .srfm-success-box-description):
   Plain ul/ol/li HTML has no .ql-editor wrapper so the Quill-scoped CSS
   never applied. Tailwind/theme resets stripped default list markers.
   Fix: add list-style-type:disc/decimal with padding-left to the
   .srfm-success-box-description styles in sass/frontend/form.scss.

2. Frontend Textarea field (Quill 2.x):
   The shared mixin contained Quill 1.x li::before / CSS counter rules
   that conflicted with Quill 2.x .ql-ui child-element markers, causing
   misalignment and double markers.
   Fix: remove the Quill 1.x marker rules from the mixin (keeping only
   the neutral padding-left / list-style-type:none overrides) and move
   them into backend.scss scoped to .srfm-textarea-quill (the Quill 1.x
   block-editor canvas context only).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The confirmation message HTML (headings, blockquote, code, font size,
font family, indent, links, images, lists) is injected as plain HTML
into .srfm-success-box-description, outside any .ql-editor wrapper.
Quill and theme/Tailwind CSS resets strip most of these styles.

Reproduce the full set of Quill 1.x snow-theme display rules inside
.srfm-success-box-description so colour (inline style), alignment
(inline style), bold/italic/underline (HTML tags), headings, blockquote,
code blocks, font sizes, font families, indentation, and list markers
all render correctly after form submission.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…alignment

list-style-type: disc/decimal places markers outside the text flow, so
when list items carry text-align: center (from the Quill editor state)
the marker is pinned to the far left while text is centered — a wide gap.

Switch to the same Quill 1.x ::before pseudo-element approach used in the
editor: the marker is an inline element and travels with the text, so
center-aligned list items render with the marker and text together (same
visual as the editor). Covers bullet and ordered list at all 9 indent
levels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The AI quick draft widget registers only after the capability gate, not
'always' — reword to avoid the misleading comment flagged in review.
The create-intent payload sent automatic_payment_methods, contradicting the
client Payment Element (scoped to card via #2884) and the middleware intent
(card-only via #85). Send payment_method_types: ['card'] so plugin, client,
and server agree; avoids the manual-capture/automatic-methods 400. Ref #1487065.
…wp-element

Import createRoot from @wordpress/element instead of react-dom (React 19 readiness)
…-nested-claude-docs

chore: expand sync-public strip surface (nested CLAUDE.md, docs/, TODO.md)
…ppers

The Payment block's Customer Email / Name (and variable-amount) field dropdowns
enumerated top-level blocks only, so fields inside container blocks were never
listed — notably the User Registration block (srfm/register), whose Email
(srfm/email) and First/Last/Username (srfm/input) live as innerBlocks, and the
Address block (srfm/address). Flatten the block tree (innerBlocks) before
filtering so nested fields are selectable. Filters are unchanged.
- Track ai_dashboard_widget_used as an analytics event (events_record) instead
  of numeric_values, which isn't ingested downstream
- Use @SInCE x.x.x placeholders for the new functions and tests
- Rewrite dashboard-widget tests to assert behavior (widget registration and
  counter increment) instead of grepping method source
- Move the AI dashboard widget script out of the render callback via
  wp_add_inline_script + wp_localize_script (Plugin Check friendly)
- Add a server-side prompt length cap in generate_ai_form
- Document the intentional react-hooks/exhaustive-deps disable in AiFormBuilder
…lattenBlocks

Addresses review feedback on #2918:
- Exclude srfm/repeater descendants from the Email/Name/amount mappers — they
  share one slug class and submit as indexed arrays, so they cannot resolve to a
  single payment customer email/name value (broke Stripe and PayPal)
- Extract the recursive block-flatten into a single exported flattenBlocks helper
  in Helpers.js (repeater guard exposed via an excludeChildrenOf option); remove
  the inlined copy in the Payment block
- Drop srfm/address inner inputs (City/State/Line 1) from the Customer Name
  dropdown to cut UX noise; they still resolve everywhere else
The check-test-coverage CI job requires a test for the new
enqueue_ai_dashboard_widget_assets() function. Assert the dashboard-only gate
and that the widget script is enqueued with its localized config for a capable
user.
…filter docs

Addresses review feedback on #2911:
- Drop the && isValidEmail gate in the blur handler so the RFC 5321 length
  message wins whenever set, matching the submit path
- Extract a documented Field_Validation::get_email_char_limits() helper holding
  the srfm_email_field_char_limits filter (docblock + @SInCE, 0-disables noted);
  validate_form_data() now consumes it
- Localize the resolved limits into srfm_submit and read them client-side via a
  single getEmailCharLimits() helper, deduping the hardcoded 64/255 literals so a
  filter that raises a limit no longer false-blocks valid input client-side
- Add test_get_email_char_limits() covering defaults and a filter override
- Add missing per-<li> base padding-left/padding-right (canonical Quill
  1.3.7) to mixins.scss, backend.scss, form.scss, and admin.php
- Add RTL indent rules (indent-1 through indent-9) to confirmation
  message in form.scss, which renders outside .ql-editor with no
  vendor-stylesheet fallback
- Extract @mixin srfm-quill-1x-list-markers in mixins.scss and replace
  four copies of the ~30-line counter block with a single @include
- Hoist the two identical wp_add_inline_style CSS strings in admin.php
  into a shared Admin::QUILL_1X_INLINE_CSS class constant

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-draft

feat: dashboard AI quick draft (#2738)
vanshk141999 and others added 29 commits July 2, 2026 17:09
…ested-fields

fix(payment): list container-block child fields in Email/Name mappers (#2917)
…d-only-payload

fix(payments): pin one-time Stripe intent payload to card
Covers the new wp_add_inline_style( ..., QUILL_1X_INLINE_CSS ) wiring in
Admin::enqueue_styles(), mirroring the existing test_enqueue_scripts()
reflection-based check. Satisfies the check-test-coverage gate.
…-shared-component

fix: restore bullet point visibility in react-quill admin editor
…ields

fix: Reset Form option now resets Dropdown and dispatches srfm_form_reset for Pro fields
…etadata

feat(entries): pass per-log retry metadata through the logs REST response
…th-limits

feat(email): enforce RFC 5321 length limits (64 local / 255 domain) with filter
Sync inc/lib/bsf-analytics from brainstormforce/bsf-analytics tag 1.1.29:
- Add 'spectra-blocks' slug to UTM analytics (modules/utm-analytics.php)
- Bump version.json to 1.1.29 and update changelog.txt
…1.29

chore: update BSF Analytics library to 1.1.29
chore: update 2.12.1 release date to 8th July 2026
Auto-generated by /i18n command on PR #2923
Replaces npm install --force with npm ci in push-to-deploy.yml and
push-asset-readme-update.yml, matching the workflows that already use
npm ci (playwright, code-analysis, release-tag-draft, update-translations).
npm ci installs from the committed lockfile without re-resolving peer deps,
so the --force ERESOLVE workaround is no longer needed. Non-breaking:
neither workflow touches package.json before install, and npm ci installs
the devDependencies that npm run build needs.
ci: pin WP-CLI to v2.12.0 in update-translations workflow
@vanshk141999
vanshk141999 merged commit 590625e into master Jul 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants