Skip to content

Add tree search, URL deep linking, clipboard copy, and improved X++ syntax highlighting#40

Merged
calebblanchardargano merged 16 commits intomasterfrom
feature/search_and_urls
Apr 10, 2026
Merged

Add tree search, URL deep linking, clipboard copy, and improved X++ syntax highlighting#40
calebblanchardargano merged 16 commits intomasterfrom
feature/search_and_urls

Conversation

@calebblanchardargano
Copy link
Copy Markdown
Contributor

Summary

Adds four major features to the AOT Browser to improve navigation, shareability, and code readability.

Features

🔍 Tree Search

  • Inline search bar (always visible) on the tree control using the Docentric filter pattern
  • Search-as-you-type — automatically finds the next matching node as the user types
  • Navigate Up/Down buttons to cycle through matches

🔗 URL Deep Linking & Clipboard Copy

  • Copy Link button in the action pane generates a shareable URL to the current object and tree node
  • URLs include ObjectType, ObjectName, and TreePath parameters for node-level navigation
  • Uses an extensible control with JavaScript navigator.clipboard.writeText() for clipboard access
  • On form load, URL parameters are read via Global::getClientURLQueryValue() to restore the exact view

🎨 X++ Syntax Highlighting Improvements

  • Complete rewrite of XPlusPlusLexer.cs with proper X++ token rules:
    • Full X++ keyword set (including ttsbegin/ttscommit, changecompany, container, etc.)
    • Data access keywords (select, firstonly, forupdate, join, where, order by, etc.)
    • Intrinsic functions (classStr, tableNum, fieldNum, etc.) highlighted as builtins
    • X++ string literals (single-quoted 'strings') and @"verbatim strings"
    • XML doc comments (///) distinguished from regular comments
    • Removed C#-only keywords that don't apply to X++
  • Cross-referenced with the official VS LanguageService Tokens enum — added 15 missing keywords

🛠️ Other

  • BP warnings resolved (0 errors, 0 warnings)
  • Documentation added for tree search and deep linking features

Files Changed

  • 10 new metadata files (classes, forms, resources, labels)
  • XPlusPlusLexer.cs — rewritten lexer rules (~140 lines changed)
  • ARBAOTBrowser.xml — form logic for search, deep linking, copy link (~300 lines added)
  • 3 new doc files

Caleb Blanchard and others added 16 commits April 9, 2026 14:15
Tree Search:
- Search button opens a dialog to enter search text
- Recursively walks the tree to find matching nodes (case-insensitive)
- Next/Prev buttons navigate between matches with wrap-around
- Search state clears when switching to a different object

URL Deep Linking:
- New ARBAOTBrowserUrlHelper class builds shareable URLs
- init() parses ObjectType, ObjectName, TreePath query parameters
- Copy Link button in action pane shows the URL in the infolog
- URL format: ?mi=ARBAOTBrowser&ObjectType=Table&ObjectName=CustTable

Co-authored-by: Copilot <[email protected]>
Replace info()-based Copy Link with a proper browser clipboard copy
using a JavaScript extensible control pattern:
- ARBClipboardHelperBuild: design-time build class
- ARBClipboardHelperControl: runtime control with FormProperty
- ARBClipboardHelper form: transient dialog hosting the control
- ARBClipboardHelper class: static copyToClipboard() entry point
- HTML/JS resources using navigator.clipboard.writeText()

The dialog opens briefly when Copy Link is clicked, copies the URL
to the browser clipboard via JavaScript, then auto-closes after 2s.

Co-authored-by: Copilot <[email protected]>
Extensible control resources (HTML/JS) must be copied to the IIS
webroot/resources/ folder for the browser to load them. Add an
automatic deployment step to Mount.ps1 that copies resource content
from AxResource/ResourceContent/ to the webroot.

Co-authored-by: Copilot <[email protected]>
HttpContext::Current is null during form init() in D365FO's SPA
architecture. Replace with Global::getClientURLQueryValue() which
uses SessionContext to access the original browser URL parameters.

Co-authored-by: Copilot <[email protected]>
CopyLinkButton now captures the currently selected tree node path
via ARBAOTBrowserUrlHelper::getSelectedTreePath() and includes it
as a TreePath parameter in the URL. When opened, the form navigates
directly to that tree node.

Co-authored-by: Copilot <[email protected]>
Replace dialog-based tree search with inline filter group using the
Docentric pattern (DocReportUserDefinedPlaceholderExpressionDesigner).

Changes:
- Add TreeSearchFilterGroup with StringControl + Prev/Next buttons
  inside DetailsNavigationList, above the ObjectTree
- TreeSearchButton in action pane now toggles filter group visibility
- Pre-build ascending/descending search index lists after tree
  construction (buildSearchTreeItems/buildSearchTreeItemsRecursive)
- Use match() for wildcard-aware search via findTreeItem()
- Remove old dialog-based methods (treeSearchExecute, treeSearchClear,
  treeSearchCollectMatches, treeSearchNavigate)

Co-authored-by: Copilot <[email protected]>
- Remove ImageOnly display so Search button shows text label
- Rewrite findTreeItem to skip-past-current approach instead of
  fragile +1/-1 index arithmetic
- Use strContains for plain text (case-insensitive substring match),
  reserve match() for wildcard patterns (* and ?)
- Change findTreeItem to public for DataControl access

Co-authored-by: Copilot <[email protected]>
- Remove NormalImage from Search toggle button (text-only display)
- Add enter() override on TreeSearchString so pressing Enter triggers
  Find Next automatically

Co-authored-by: Copilot <[email protected]>
- Remove Search toggle button from action pane (no longer needed)
- Show TreeSearchFilterGroup always (remove Visible=No)
- Replace enter() with modified() on TreeSearchString so search
  triggers automatically as the user types and tabs/clicks away

Co-authored-by: Copilot <[email protected]>
- Replace C#-centric keyword list with accurate X++ keywords
  - Add: final, implements, retry, next, firstonly, forupdate, nofetch,
    forceselectorder, crosscompany, display, edit, server, client,
    ttsbegin/ttscommit/ttsabort, changecompany, mod, div, and more
  - Remove 30+ C#-only keywords (async, await, unsafe, stackalloc, etc.)
- Replace type keywords with X++ types (int64, utcdatetime, guid, anytype,
  boolean, container, tableId, fieldId, classId, etc.)
- Add XML doc comment (///) highlighting as String.Doc token type
- Add label literal (@sys12345, @module:Label) highlighting as Name.Label
- Add intrinsic function highlighting (classStr, tableStr, enumStr, etc.)
  as Name.Builtin with green bold styling
- Add ClassName:: static access highlighting (class name as Name.Class)
- Separate operators from punctuation for distinct visual styling
- Add macro usage (#MacroName) highlighting as Comment.Preproc
- Add additional preprocessor directives (globaldefine, defjob, etc.)

Co-authored-by: Copilot <[email protected]>
- Add XML doc summary to ARBClipboardHelperBuild and ARBClipboardHelperControl
- Fix HTML-encoded summary tags in ARBClipboardHelper and ARBAOTBrowserUrlHelper
- Change ARBClipboardHelperControl constructor from public to protected
- Remove unnecessary strFmt() call on label with no format args
- Add missing returns tag on TreeSearchString.modified() doc header

Co-authored-by: Copilot <[email protected]>
Cross-referenced our lexer against the official Tokens enum from
Microsoft.Dynamics.Framework.Tools.LanguageService.Parser and added
15 missing keywords:

- event, eventhandler (event handling)
- firstonly100, firstonly1000 (select hints)
- from (insert_recordset ... from)
- generateonly (select modifier)
- hint, index (index hint)
- optimisticlock, pessimisticlock, repeatableread (concurrency)
- print (debug output)
- reverse (select ordering)
- set, unchecked (misc keywords)

Co-authored-by: Copilot <[email protected]>
@calebblanchardargano calebblanchardargano merged commit 8dd7fca into master Apr 10, 2026
1 check passed
@calebblanchardargano calebblanchardargano deleted the feature/search_and_urls branch April 10, 2026 12:46
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.

1 participant