mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
Migrate to Bootstrap 5 (#7582)
This PR completes the migration from Bootstrap 4 to Bootstrap 5.3.5 following the plan outlined in [docs/Bootstrap5Migration.md](https://github.com/compiler-explorer/compiler-explorer/blob/mg/bootstrap5/docs/Bootstrap5Migration.md). ## Migration Process We followed a phased approach as documented in the migration plan: 1. **Phase 1: Dependency Updates and Basic Setup** - Updated Bootstrap from 4.6.2 to 5.3.5 - Added @popperjs/core dependency (replacing Popper.js) - Updated Tom Select theme from bootstrap4 to bootstrap5 2. **Phase 2: Global CSS Class Migration** - Updated directional utility classes (ml/mr → ms/me) - Updated floating utility classes (float-left/right → float-start/end) - Updated text alignment classes (text-left/right → text-start/end) 3. **Phase 3: HTML Attribute Updates** - Updated data attributes to use Bootstrap 5 prefixes (data-bs-toggle, data-bs-target, etc.) - Fixed tab navigation issues 4. **Phase 4: JavaScript API Compatibility Layer** - Created bootstrap-utils.ts compatibility layer - Updated component initialization for modals, dropdowns, popovers, etc. 5. **Phase 5: Component Migration** - Updated and tested specific components (modals, dropdowns, toasts, etc.) - Fixed styling issues in cards and button groups 6. **Phase 6: Form System Updates** - Updated form control classes to Bootstrap 5 standards - Updated checkbox/radio markup patterns - Simplified input groups 7. **Phase 7: Navbar Structure Updates** - Updated navbar structure with container-fluid - Fixed responsive behavior 8. **Phase 8: SCSS Variables and Theming** - Added custom CSS fixes for navbar alignment - Verified theme compatibility 9. **Phase 9: Accessibility Improvements** - Updated sr-only to visually-hidden - Added proper ARIA attributes - Enhanced screen reader support ## Key Changes - No more jQuery dependency in Bootstrap 5 - New prefix for data attributes (data-bs-*) - Improved accessibility with ARIA attributes - Updated positioning classes (start/end instead of left/right) - Simplified input group structure ## Test Plan 1. **Navigation Testing** - Verify all dropdown menus open and close properly - Test mobile menu responsiveness - Check tab navigation in settings dialog 2. **Component Testing** - Verify all modals open and close correctly (settings, share, load/save) - Test tooltips and popovers - Check form controls in different dialogs 3. **Layout Testing** - Test responsiveness on different screen sizes - Verify proper alignment of elements - Check dark mode compatibility 4. **Specific Features to Test** - Compiler selection and options - Share dialog functionality - Settings dialog - Tree view (IDE mode) - Font selection dropdown 5. **Browser Testing** - Test in Chrome, Firefox, Safari - Test in mobile browsers ## Note on Further Improvements After this migration is stable, we could consider Phase 12: removing jQuery dependency entirely, as Bootstrap 5 no longer requires it. This would be a separate effort. --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
2
.idea/watcherTasks.xml
generated
2
.idea/watcherTasks.xml
generated
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectTasksOptions" suppressed-tasks="Less;Babel;Pug/Jade" />
|
<component name="ProjectTasksOptions" suppressed-tasks="Less;Babel;Pug/Jade;SCSS" />
|
||||||
</project>
|
</project>
|
||||||
62
CLAUDE.md
Normal file
62
CLAUDE.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Build & Test Commands
|
||||||
|
- Build: `npm run webpack`, `npm start`
|
||||||
|
- Dev Mode: `make dev`, `make gpu-dev`
|
||||||
|
- Lint: `npm run lint` (auto-fix), `npm run lint-check` (check only)
|
||||||
|
- Type Check: `npm run ts-check`
|
||||||
|
- Test: `npm run test` (all), `npm run test-min` (minimal)
|
||||||
|
- Test Single File: `npm run test -- --run base-compiler-tests.ts`
|
||||||
|
- Test Specific Pattern: `npm run test -- -t "should handle execution failures"`
|
||||||
|
- Cypress Tests: `npm run cypress`
|
||||||
|
- Pre-commit Check: `make pre-commit` or `npm run check`
|
||||||
|
|
||||||
|
## Important Workflow Requirements
|
||||||
|
- ALWAYS run `npm run lint` before any git operations (`git add`, `git commit`, etc.)
|
||||||
|
- The linter will automatically fix formatting issues, so this must be run before committing
|
||||||
|
- Failing to run the linter may result in style issues and commit failures
|
||||||
|
|
||||||
|
## Style Guidelines
|
||||||
|
- TypeScript: Strict typing, no implicit any, no unused locals
|
||||||
|
- Formatting: 4-space indentation, 120 char line width, single quotes
|
||||||
|
- No semicolon omission, prefer const/let over var
|
||||||
|
- Client-side: TypeScript transpiled to ES5 JavaScript. This process requires import of `blah.js` even though `blah.ts` is the actual filename
|
||||||
|
- ALWAYS place imports at the top of files, never inside functions or methods, unless absolutely necessary (and confirm before proposing)
|
||||||
|
- Use Underscore.js for utility functions
|
||||||
|
- Write tests for new server-side components
|
||||||
|
- Where appropriate suggest follow-up improvements to code to improve code quality, and DRY up where feasible
|
||||||
|
- Documentation is in `docs/` directory; update where necessary, in particular if anything about the RESTful API changes
|
||||||
|
- Don't add comments above code that's clearly self-documenting. For example, don't put comments like this:
|
||||||
|
```
|
||||||
|
// Initialises the thing
|
||||||
|
initialiseThing();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Guidelines
|
||||||
|
- Use Vitest for unit tests (compatible with Jest syntax)
|
||||||
|
- Tests are in the `/test` directory, typically named like the source files they test
|
||||||
|
- Use spy functions with `vi.spyOn()` for mocking dependencies
|
||||||
|
- Test structure follows describe/it pattern with descriptive test names
|
||||||
|
- Separate tests with clear section headers using comments for readability
|
||||||
|
- Consider cross-platform compatibility (especially Windows path handling)
|
||||||
|
- For complex files, organize tests by functionality rather than by method
|
||||||
|
- Use `beforeEach`/`afterEach` to set up and clean up test environment
|
||||||
|
- Remember to restore mocks with `vi.restoreAllMocks()` after tests
|
||||||
|
- Test both success and error cases
|
||||||
|
- Coverage is available with `npm test:coverage`
|
||||||
|
- For Windows-specific path issues, either:
|
||||||
|
- Skip tests with `if (process.platform === 'win32') return;`
|
||||||
|
- Write platform-specific assertions
|
||||||
|
- Use path-agnostic checks
|
||||||
|
|
||||||
|
## Compiler Testing Specifics
|
||||||
|
- Mock filesystem operations when testing file I/O
|
||||||
|
- Use `makeFakeCompilerInfo()` for creating test compiler configurations
|
||||||
|
- Use `makeCompilationEnvironment()` to create test environments
|
||||||
|
- Mock `exec` calls for testing compilation and execution
|
||||||
|
- For BaseCompiler, use the test utils from `/test/utils.js`
|
||||||
|
- Test specific combinations of compiler capabilities
|
||||||
|
- Focus tests on behavior, not implementation details
|
||||||
|
- Use platform-agnostic assertions where possible
|
||||||
@@ -89,6 +89,8 @@ and shorter startup times.
|
|||||||
|
|
||||||
You can also use `npm run dev` to run if `make dev` doesn't work on your machine.
|
You can also use `npm run dev` to run if `make dev` doesn't work on your machine.
|
||||||
|
|
||||||
|
When making UI changes, we recommend following the [UI Testing Checklist](docs/TestingTheUi.md) to ensure all components work correctly.
|
||||||
|
|
||||||
Some languages need extra tools to demangle them, e.g. `rust`, `d`, or `haskell`. Such tools are kept separately in the
|
Some languages need extra tools to demangle them, e.g. `rust`, `d`, or `haskell`. Such tools are kept separately in the
|
||||||
[tools repo](https://github.com/compiler-explorer/compiler-explorer-tools).
|
[tools repo](https://github.com/compiler-explorer/compiler-explorer-tools).
|
||||||
|
|
||||||
|
|||||||
387
docs/Bootstrap5Migration.md
Normal file
387
docs/Bootstrap5Migration.md
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
# Bootstrap 5 Migration Plan
|
||||||
|
|
||||||
|
This document outlines the step-by-step process for migrating Compiler Explorer from Bootstrap 4 to Bootstrap 5.3.5. The
|
||||||
|
migration will be completed incrementally to allow for testing between steps.
|
||||||
|
|
||||||
|
## Migration Strategy
|
||||||
|
|
||||||
|
We'll break down the migration into smaller, testable chunks rather than making all changes at once. This approach
|
||||||
|
allows for:
|
||||||
|
|
||||||
|
- Easier identification of issues
|
||||||
|
- Progressive testing by project maintainers
|
||||||
|
- Minimizing disruption to the codebase
|
||||||
|
|
||||||
|
**Progress tracking will be maintained in this document.**
|
||||||
|
|
||||||
|
## Phases & Current Progress
|
||||||
|
|
||||||
|
### Phase 1: Dependency Updates and Basic Setup ✅
|
||||||
|
|
||||||
|
- [x] Update package.json with Bootstrap 5.3.5
|
||||||
|
- [x] Add @popperjs/core dependency (replacing Popper.js)
|
||||||
|
- [x] Update Tom Select theme from bootstrap4 to bootstrap5
|
||||||
|
- [x] Update main import statements where Bootstrap is initialized
|
||||||
|
- [x] Update webpack configuration if needed for Bootstrap 5 compatibility
|
||||||
|
- [x] Verify the application still builds and runs with basic functionality
|
||||||
|
|
||||||
|
#### Notes for Human Testers (Phase 1)
|
||||||
|
|
||||||
|
- At this phase, the application will have console errors related to Bootstrap component initialization
|
||||||
|
- Tom Select dropdowns (like compiler picker) may have styling differences with the new bootstrap5 theme
|
||||||
|
- Initial page load should still work, but dropdown functionality will be broken
|
||||||
|
- Modal dialogs like Settings and Sharing may not function correctly
|
||||||
|
- The primary layout and basic display of panes should still function
|
||||||
|
|
||||||
|
### Phase 2: Global CSS Class Migration ✅
|
||||||
|
|
||||||
|
- [x] Update directional utility classes (ml/mr → ms/me)
|
||||||
|
- [x] Search and replace in .pug templates
|
||||||
|
- [x] Search and replace in .scss files
|
||||||
|
- [x] Search and replace in JavaScript/TypeScript files that generate HTML
|
||||||
|
- [x] Update floating utility classes (float-left/right → float-start/end)
|
||||||
|
- [x] Update text alignment classes (text-left/right → text-start/end)
|
||||||
|
- [x] Update other renamed classes (badge-pill → rounded-pill, etc.)
|
||||||
|
- [x] Test and verify styling changes
|
||||||
|
|
||||||
|
#### Notes for Human Testers (Phase 2)
|
||||||
|
|
||||||
|
- Look for proper spacing and margin alignment in the UI
|
||||||
|
- Specific components to check:
|
||||||
|
- Compiler output area: Check the spacing in compiler.pug (short-compiler-name, compile-info spans)
|
||||||
|
- Navbar spacing: The navbar items should maintain proper spacing (ms/me instead of ml/mr)
|
||||||
|
- Code editor components: Check the button and icon alignment in codeEditor.pug
|
||||||
|
- Tree view components: The tree.pug file had utility class changes
|
||||||
|
- Alert messages (widgets/alert.ts): Check that toast messages appear with correct alignment
|
||||||
|
- Compiler picker (compiler-picker.ts and compiler-picker-popup.ts): Check dropdown spacing
|
||||||
|
- Rounded badge display in menu-policies.pug (now using rounded-pill instead of badge-pill)
|
||||||
|
- The float-end class replaces float-right in the index.pug file's copy buttons
|
||||||
|
- Any LTR/RTL layout impacts should be especially checked for correct directionality
|
||||||
|
|
||||||
|
### Phase 3: HTML Attribute Updates ✅
|
||||||
|
|
||||||
|
- [x] Update data attributes across the codebase
|
||||||
|
- [x] data-toggle → data-bs-toggle
|
||||||
|
- [x] data-target → data-bs-target
|
||||||
|
- [x] data-dismiss → data-bs-dismiss
|
||||||
|
- [x] data-ride → data-bs-ride (not used in codebase)
|
||||||
|
- [x] data-spy → data-bs-spy (not used in codebase)
|
||||||
|
- [x] Other data attributes as needed
|
||||||
|
- [x] Test components to ensure they function correctly with new attributes
|
||||||
|
|
||||||
|
#### Notes for Human Testers (Phase 3)
|
||||||
|
|
||||||
|
- This phase should restore basic functionality of several Bootstrap components
|
||||||
|
- Specific components to check:
|
||||||
|
- Dropdowns: All dropdown menus throughout the application should open/close properly
|
||||||
|
- Modal dialogs: Settings, Sharing, and other modal dialogs should open/close correctly
|
||||||
|
- Tooltips: Hover tooltips (using data-bs-toggle="tooltip") should display properly
|
||||||
|
- Popovers: Any popovers used in the UI should function correctly
|
||||||
|
- Collapse components: Any collapsible sections should toggle properly
|
||||||
|
- Tabs: Any tabbed interfaces should switch between tabs correctly
|
||||||
|
- Watch for console errors related to Bootstrap component initialization
|
||||||
|
- Some JavaScript component initialization may still be broken until Phase 4 is completed
|
||||||
|
|
||||||
|
### Phase 4: JavaScript API Compatibility Layer ✅
|
||||||
|
|
||||||
|
- [x] Create a temporary Bootstrap compatibility utility module to abstract component initialization
|
||||||
|
- [x] Implement a hybrid approach with `bootstrap-utils.ts` as a compatibility layer
|
||||||
|
- [x] Mark clearly as temporary code to be removed after migration is complete
|
||||||
|
- [x] Define methods for each component type (Modal, Dropdown, Toast, etc.)
|
||||||
|
- [x] Update component initialization in key files:
|
||||||
|
- [x] widgets/alert.ts (modals and toasts)
|
||||||
|
- [x] sharing.ts (modals, tooltips, and dropdowns)
|
||||||
|
- [x] compiler-picker-popup.ts (modals)
|
||||||
|
- [x] load-save.ts (modals)
|
||||||
|
- [x] Other files with Bootstrap component initialization:
|
||||||
|
- [x] **Modal Initialization**:
|
||||||
|
- [x] widgets/site-templates-widget.ts
|
||||||
|
- [x] widgets/runtime-tools.ts
|
||||||
|
- [x] widgets/compiler-overrides.ts
|
||||||
|
- [x] widgets/timing-info-widget.ts
|
||||||
|
- [x] widgets/history-widget.ts
|
||||||
|
- [x] widgets/libs-widget.ts
|
||||||
|
- [x] main.ts
|
||||||
|
- [x] **Dropdown Handling**:
|
||||||
|
- [x] panes/tree.ts
|
||||||
|
- [x] panes/compiler.ts
|
||||||
|
- [x] panes/editor.ts
|
||||||
|
- [x] **Popover Handling**:
|
||||||
|
- [x] main.ts
|
||||||
|
- [x] widgets/compiler-version-info.ts
|
||||||
|
- [x] panes/executor.ts
|
||||||
|
- [x] panes/conformance-view.ts
|
||||||
|
- [x] panes/cfg-view.ts
|
||||||
|
- [x] Test the compatibility layer with basic components
|
||||||
|
|
||||||
|
#### Notes for Human Testers (Phase 4)
|
||||||
|
|
||||||
|
- This is one of the most critical phases as it involves creating a compatibility layer for the JavaScript API
|
||||||
|
- A new utility file will be created for component initialization that abstracts Bootstrap 5's new approach
|
||||||
|
- Key differences to watch for:
|
||||||
|
- Modal initialization and events: Bootstrap 5 uses a completely different event system
|
||||||
|
- Dropdown initialization: Works with data attributes but requires `data-bs-toggle` instead of `data-toggle`
|
||||||
|
- Toast components: The API has changed significantly
|
||||||
|
- Popover/Tooltip initialization: API changes but still support data attributes with proper prefixes
|
||||||
|
- Components to thoroughly test:
|
||||||
|
- Alert dialogs (widgets/alert.ts): Check all types of alerts (info, warning, error)
|
||||||
|
- Sharing functionality (sharing.ts): The share modal should work properly
|
||||||
|
- Compiler picker popup (compiler-picker-popup.ts): Should display and function correctly
|
||||||
|
- All dropdown menus: Should open and close properly
|
||||||
|
- All tooltips and popovers: Should display correctly on hover/click
|
||||||
|
- Watch for event handling issues where Bootstrap 4 events no longer exist or are renamed
|
||||||
|
|
||||||
|
### Phase 5: Component Migration (By Component Type) ✅
|
||||||
|
|
||||||
|
#### Modal Component Migration
|
||||||
|
|
||||||
|
- [x] Update modal implementation in alert.ts
|
||||||
|
- [x] Update modal usage in compiler-picker-popup.ts
|
||||||
|
- [x] Update modal handling in load-save.ts
|
||||||
|
- [x] Update modal event handling in sharing.ts
|
||||||
|
- [x] Test modal functionality thoroughly
|
||||||
|
|
||||||
|
#### Dropdown Component Migration
|
||||||
|
|
||||||
|
- [x] Update dropdown handling in sharing.ts
|
||||||
|
- [x] Update dropdown usage in compiler.ts, editor.ts, etc.
|
||||||
|
- [x] Test dropdown functionality thoroughly
|
||||||
|
|
||||||
|
#### Toast/Alert Component Migration
|
||||||
|
|
||||||
|
- [x] Update toast implementation in alert.ts
|
||||||
|
- [x] Update toast styling in explorer.scss
|
||||||
|
- [x] Test toast notifications and alerts
|
||||||
|
|
||||||
|
#### Popover/Tooltip Migration
|
||||||
|
|
||||||
|
- [x] Update tooltip initialization in sharing.ts
|
||||||
|
- [x] Update popover usage in compiler.ts, executor.ts, editor.ts, etc.
|
||||||
|
- [x] Test popover and tooltip functionality thoroughly
|
||||||
|
|
||||||
|
#### Card Component Updates
|
||||||
|
|
||||||
|
- [x] Review card usage and update to Bootstrap 5 standards
|
||||||
|
- [x] ~~Replace any card-deck implementations with grid system~~ (Not needed - card-deck not used in codebase)
|
||||||
|
- [x] Test card layouts, especially tab navigation within cards
|
||||||
|
|
||||||
|
#### Collapse Component Updates
|
||||||
|
|
||||||
|
- [x] ~~Update any collapse component implementations~~ (Not needed - minimal collapse usage in codebase)
|
||||||
|
- [x] Test collapse functionality (limited to navbar hamburger menu on mobile)
|
||||||
|
|
||||||
|
#### Button Group Updates
|
||||||
|
|
||||||
|
- [x] Review button group implementations
|
||||||
|
- [x] Update to Bootstrap 5 standards (no changes needed - Bootstrap 5 maintains same button group classes)
|
||||||
|
- [x] Test button group functionality in toolbars and dropdown menus
|
||||||
|
|
||||||
|
### Phase 6: Form System Updates ✅
|
||||||
|
|
||||||
|
- [x] Update form control classes to Bootstrap 5 standards
|
||||||
|
- [x] Update input group markup and classes
|
||||||
|
- [x] Update checkbox/radio markup to Bootstrap 5 standards
|
||||||
|
- [x] Update form validation classes and markup
|
||||||
|
- [x] ~~Consider implementing floating labels where appropriate (new in Bootstrap 5)~~ (Not needed for existing form
|
||||||
|
usage)
|
||||||
|
- [x] Test form functionality and appearance
|
||||||
|
|
||||||
|
### Phase 7: Navbar Structure Updates ✅
|
||||||
|
|
||||||
|
- [x] Update navbar structure in templates to match Bootstrap 5 requirements
|
||||||
|
- [x] Review custom navbar styling in explorer.scss
|
||||||
|
- [x] Test responsive behavior of navbar
|
||||||
|
- [x] Ensure mobile menu functionality works correctly
|
||||||
|
- [x] ~~Consider implementing offcanvas for mobile navigation (new in Bootstrap 5)~~ (Standard navbar collapse is
|
||||||
|
sufficient for current needs)
|
||||||
|
|
||||||
|
### Phase 8: SCSS Variables and Theming ✅
|
||||||
|
|
||||||
|
- [x] Review any custom SCSS that extends Bootstrap functionality
|
||||||
|
- [x] Update any custom themes to use Bootstrap 5 variables
|
||||||
|
- [x] Check z-index variable changes in Bootstrap 5
|
||||||
|
- [x] Add navbar container padding fix for proper alignment
|
||||||
|
- [x] Test theme switching functionality
|
||||||
|
|
||||||
|
### Phase 9: Accessibility Improvements ✅
|
||||||
|
|
||||||
|
- [x] Review ARIA attributes in custom component implementations
|
||||||
|
- [x] Leverage Bootstrap 5's improved accessibility features
|
||||||
|
- [x] Add ARIA labels and live regions for dynamic content
|
||||||
|
- [x] Enhance form controls with proper accessibility attributes
|
||||||
|
- [ ] ~~Test with screen readers and keyboard navigation~~ (left for future work)
|
||||||
|
- [ ] ~~Ensure color contrast meets accessibility guidelines~~ (left for future work)
|
||||||
|
|
||||||
|
### Phase 10: Final Testing and Refinement ✅
|
||||||
|
|
||||||
|
- [x] ~~Comprehensive testing across different viewports~~ cursory testing with a few viewports
|
||||||
|
- [x] Cross-browser testing (at least; looked in FireFox and we're good)
|
||||||
|
- [x] Fix any styling issues or inconsistencies
|
||||||
|
- [x] ~~Performance testing (Bootstrap 5 should be more performant)~~ (don't care; site is fine)
|
||||||
|
- [x] Ensure no regressions in functionality
|
||||||
|
|
||||||
|
## Key Learnings From Implementation
|
||||||
|
|
||||||
|
These insights were gathered during the migration process and may be helpful for future reference:
|
||||||
|
|
||||||
|
- **Data Attributes Still Work Without JavaScript Initialization**: Despite some documentation suggesting otherwise,
|
||||||
|
Bootstrap 5 components with data attributes (like tabs) still work without explicit JavaScript initialization. The key
|
||||||
|
is using the correct `data-bs-*` prefix.
|
||||||
|
- **Close Button Implementation Completely Changed**: Bootstrap 4 used `.close` class with a `×` entity inside a
|
||||||
|
span, while Bootstrap 5 uses `.btn-close` class with a background image and no inner content.
|
||||||
|
- **Tab Navigation Issues**: The tab navigation problems were fixed by simply updating data attributes, not by adding
|
||||||
|
JavaScript initialization.
|
||||||
|
- **jQuery Plugin Methods Removal**: jQuery methods like `.popover()` and `.dropdown('toggle')` need to be replaced with
|
||||||
|
code that uses the Bootstrap 5 API through a compatibility layer. Always use `BootstrapUtils` helper methods rather
|
||||||
|
than direct jQuery plugin calls.
|
||||||
|
- **Grid and Form Class Renaming**: Bootstrap 5 renamed several core classes, such as changing `.form-row` to `.row`.
|
||||||
|
This can cause subtle template selector issues in code that relies on these class names.
|
||||||
|
- **Don't Mix Data Attributes and JavaScript Modal Creation**: When creating modals via JavaScript (e.g., for
|
||||||
|
dynamically loaded content), don't include `data-bs-toggle="modal"` on the trigger element unless you also add a
|
||||||
|
matching `data-bs-target` attribute pointing to a valid modal element.
|
||||||
|
- **Modal Events Changed Significantly**: Bootstrap 5 modal events need to be attached directly to the native DOM
|
||||||
|
element rather than jQuery objects, and the event parameter type is different. For proper typing, import the `Modal`
|
||||||
|
type from bootstrap and use `Modal.Event` type.
|
||||||
|
- **jQuery Event Binding vs Native DOM Events**: Bootstrap 5 requires native DOM event binding instead of jQuery's
|
||||||
|
`.on()` method. Replace `$(selector).on('shown.bs.modal', handler)` with
|
||||||
|
`domElement.addEventListener('shown.bs.modal', handler)`. This is particularly important for modal events like '
|
||||||
|
shown.bs.modal'.
|
||||||
|
- **Tooltip API Changed**: The global `window.bootstrap.Tooltip` reference no longer exists. Import the `Tooltip` class
|
||||||
|
directly from bootstrap instead.
|
||||||
|
- **Input Group Structure Simplified**: Bootstrap 5 removed the need for `.input-group-prepend` and
|
||||||
|
`.input-group-append` wrapper divs. Buttons and other controls can now be direct children of the `.input-group`
|
||||||
|
container. This simplifies the markup but requires template updates.
|
||||||
|
- **TomSelect Widget Integration**: Bootstrap 5's switch from CSS triangles to SVG background images for dropdowns
|
||||||
|
caused issues with TomSelect. Adding back custom CSS for dropdown arrows was necessary to maintain correct appearance.
|
||||||
|
- **Btn-block Removed**: Bootstrap 5 removed the `.btn-block` class. Instead, the recommended approach is to wrap
|
||||||
|
buttons in a container with `.d-grid` and use standard `.btn` classes. This affects any full-width buttons in the
|
||||||
|
application.
|
||||||
|
- **Element Selection for Components**: When working with Bootstrap 5 components, prefer passing CSS selectors to
|
||||||
|
`BootstrapUtils` methods rather than jQuery objects, as this provides more consistent behavior.
|
||||||
|
|
||||||
|
## Fixed Issues & Completed Work
|
||||||
|
|
||||||
|
### UI Layout & Display Issues
|
||||||
|
|
||||||
|
- [x] Font dropdown styling fixed
|
||||||
|
- [x] Templates view proportions fixed (min-width added to columns and modal)
|
||||||
|
- [x] Dialog appearance fixed (updated close buttons to use `.btn-close`)
|
||||||
|
- [x] Dropdown positioning fixed (updated to `.dropdown-menu-end`)
|
||||||
|
- [x] TomSelect dropdown arrows fixed (custom CSS implementation)
|
||||||
|
- [x] IDE mode border styling improved (temporarily with `.list-group-flush`)
|
||||||
|
- [x] Sponsors window styling fixed (replaced `.btn-block` with `.d-grid` approach)
|
||||||
|
- [x] The X to close the community/alert notes is harder to see in dark mode than before (fixed: added
|
||||||
|
`filter: invert(100%)` to make btn-close buttons visible in dark themes)
|
||||||
|
- [x] TomSelect dropdowns for compilers are excessively long (both in executor view and normal view) (fixed manually)
|
||||||
|
- [x] Default text/placeholder text is too dark, making it hard to read (especially "Compiler options") (fixed manually)
|
||||||
|
- [x] Dropdown in the library menu has changed color (fixed: updated `.custom-select` to `.form-select` in theme files)
|
||||||
|
- [x] ~~Layout has changed slightly in the library menu~~ (decided it looks better now)
|
||||||
|
- [x] The "popout" on the TomSelect compiler dropdown is misaligned (fixed: updated styling for TomSelect components)
|
||||||
|
- [x] Compiler combobox rounding overlaps left border by 1 pixel (fixed: overrode CSS variables to reset Bootstrap 5's
|
||||||
|
negative margin)
|
||||||
|
- [x] Diff view - changing left/right side compiler/window turns combobox to a white background (fixed: removed
|
||||||
|
form-select class to avoid transparent background)
|
||||||
|
- [x] The popular arguments dropdown at the right of the options isn't properly aligned (fixed: updated dropdown styling
|
||||||
|
in compiler.pug)
|
||||||
|
- [x] Long compiler names wrap instead of widening the dropdown (fixed: improved styling for TomSelect dropdowns)
|
||||||
|
|
||||||
|
### Navigation & Functional Issues
|
||||||
|
|
||||||
|
- [x] Tab navigation fixed (updated data attributes to `data-bs-toggle="tab"`)
|
||||||
|
- [x] Share dialog functionality fixed (proper Bootstrap 5 modal initialization)
|
||||||
|
- [x] Sponsors modal error fixed (removed conflicting data attributes)
|
||||||
|
- [x] Share dropdown tooltip conflict fixed (moved tooltip to parent element)
|
||||||
|
- [x] History view is broken (empty when clicking radio buttons) (fixed: updated modal event binding from jQuery's
|
||||||
|
`.on('shown.bs.modal')` to native DOM `addEventListener('shown.bs.modal')`)
|
||||||
|
- [x] Conformance view's "add compiler" functionality is broken (fixed: template selector was looking for `.form-row`
|
||||||
|
which changed to `.row` in Bootstrap 5)
|
||||||
|
- [x] Need to check for more instances of old Bootstrap v4 code patterns (fixed: replaced `dropdown('toggle')` in
|
||||||
|
main.ts with `BootstrapUtils.getDropdownInstance()` and `.toggle()`)
|
||||||
|
- [x] Runtime tools window is broken - doesn't save settings anymore (fixed: updated modal hide event handling with
|
||||||
|
setElementEventHandler)
|
||||||
|
- [x] Emulation functionality is broken due to modal issues (fixed: replaced direct .modal() calls with
|
||||||
|
BootstrapUtils.showModal)
|
||||||
|
|
||||||
|
### Code Structure Improvements
|
||||||
|
|
||||||
|
- [x] Custom classes in runtime tools selection (`.custom-runtimetool`) and overrides selection (`.custom-override`) -
|
||||||
|
removed as they were superfluous
|
||||||
|
- [x] `.form-row` still used in theme files (dark-theme.scss, one-dark-theme.scss, pink-theme.scss) - replaced with
|
||||||
|
standard `.row`
|
||||||
|
- [x] Border directional properties in explorer.scss updated for better RTL support - added `border-inline-start` and
|
||||||
|
border radius logical properties with appropriate fallbacks for older browsers
|
||||||
|
- [x] Input group structures verified - all instances of the deprecated `.input-group-prepend` and `.input-group-append`
|
||||||
|
have already been updated to use Bootstrap 5's simplified approach
|
||||||
|
- [x] Toast header close button styling verified - explorer.scss already uses `.btn-close` consistently for toast
|
||||||
|
components
|
||||||
|
- [x] Event handlers verified - history-widget.ts and sharing.ts are correctly using native DOM addEventListener methods
|
||||||
|
with the appropriate Bootstrap 5 event names
|
||||||
|
|
||||||
|
## Future Work
|
||||||
|
|
||||||
|
### Phase 11: Documentation Update
|
||||||
|
|
||||||
|
- [ ] Update any documentation that references Bootstrap components
|
||||||
|
- [ ] Document custom component implementations
|
||||||
|
- [ ] Note any deprecated features or changes in functionality
|
||||||
|
|
||||||
|
### Phase 12: Optional jQuery Removal and Cleanup
|
||||||
|
|
||||||
|
- [ ] Create a plan for jQuery removal (if desired)
|
||||||
|
- [ ] Identify non-Bootstrap jQuery usage that would need refactoring
|
||||||
|
- [ ] Remove the temporary `bootstrap-utils.ts` compatibility layer
|
||||||
|
- [ ] Replace all uses with direct Bootstrap 5 API calls
|
||||||
|
- [ ] Document the native Bootstrap 5 API for future reference
|
||||||
|
- [ ] Investigate and fix modal accessibility warnings
|
||||||
|
- [ ] Address the warning: "Blocked aria-hidden on an element because its descendant retained focus"
|
||||||
|
- [ ] Update modal template markup to leverage Bootstrap 5.3's built-in support for the `inert` attribute
|
||||||
|
- [ ] Ensure proper focus management in modals for improved accessibility
|
||||||
|
|
||||||
|
### Additional Pending Issues
|
||||||
|
|
||||||
|
- [ ] Check Sentry for additional errors on the beta site
|
||||||
|
- [ ] Investigate the "focus" selected check boxes in the settings view. They're very light when focused, in particular
|
||||||
|
in pink theme. I couldn't work out how to fix this, but it seemed minor.
|
||||||
|
- [ ] The "pop out" div that's attached to the compiler picker doesn't work on the conformance view: this was broken
|
||||||
|
before. Essentially the z-order means it's drawn behind the lower conformance compilers and `z-index` can't fix it.
|
||||||
|
Needs a rethink of how this is done.
|
||||||
|
- [ ] File tracking issues for anything on this list we don't complete.
|
||||||
|
|
||||||
|
## Final Testing Checklist
|
||||||
|
|
||||||
|
Before considering the Bootstrap 5 migration complete, a comprehensive UI testing checklist was created and used to
|
||||||
|
verify functionality. This checklist has been completed with all tests passing. The tests cover all major UI components
|
||||||
|
that could be affected by the Bootstrap migration.
|
||||||
|
|
||||||
|
The checklist included:
|
||||||
|
|
||||||
|
- Modal dialogs (Settings, Share, Load/Save, etc.)
|
||||||
|
- Dropdown components (navigation, compiler options, TomSelect)
|
||||||
|
- Toast/Alert components
|
||||||
|
- Popovers and tooltips
|
||||||
|
- Card, button group, and form components
|
||||||
|
- Specialized views (Conformance, Tree, Visualization)
|
||||||
|
- Responsive behavior
|
||||||
|
|
||||||
|
A permanent version of this UI testing checklist has been created as a separate document and can be used for testing
|
||||||
|
future UI changes or upgrades: [UI Testing Checklist](TestingTheUi.md)
|
||||||
|
|
||||||
|
## Notes for Implementation
|
||||||
|
|
||||||
|
1. **Make minimal changes** in each step to allow for easier testing and troubleshooting
|
||||||
|
2. **Test thoroughly** after each phase before moving to the next
|
||||||
|
3. **Document issues** encountered during migration for future reference
|
||||||
|
4. **Focus on accessibility** to ensure the site remains accessible throughout changes
|
||||||
|
5. **Maintain browser compatibility** with all currently supported browsers
|
||||||
|
6. **Consider performance implications** of the changes
|
||||||
|
7. **NEVER mark any issue as fixed in this document** until you have explicit confirmation from the reviewer that the
|
||||||
|
issue is completely resolved
|
||||||
|
8. **NEVER commit changes** until you have explicit confirmation that the fix works correctly
|
||||||
|
|
||||||
|
## Technical References
|
||||||
|
|
||||||
|
- [Bootstrap 5 Migration Guide](https://getbootstrap.com/docs/5.0/migration/)
|
||||||
|
- [Bootstrap 5 Components Documentation](https://getbootstrap.com/docs/5.3/components/)
|
||||||
|
- [Bootstrap 5 Utilities Documentation](https://getbootstrap.com/docs/5.3/utilities/)
|
||||||
|
- [Bootstrap 5 Forms Documentation](https://getbootstrap.com/docs/5.3/forms/overview/)
|
||||||
|
- [Popper v2 Documentation](https://popper.js.org/docs/v2/)
|
||||||
240
docs/TestingTheUi.md
Normal file
240
docs/TestingTheUi.md
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
# UI Testing Checklist for Compiler Explorer
|
||||||
|
|
||||||
|
This document provides a checklist for testing the Compiler Explorer UI components. Use this checklist for
|
||||||
|
major UI changes, framework updates, or when implementing significant new features.
|
||||||
|
|
||||||
|
## Modal Components
|
||||||
|
|
||||||
|
### Settings Modal
|
||||||
|
|
||||||
|
- Open and close using the "Settings" option in the "More" dropdown
|
||||||
|
- Test tab navigation between all tab sections (Colouring, Site behaviour, etc.)
|
||||||
|
- Verify form controls within settings (checkboxes, selects, inputs)
|
||||||
|
- Check that the close button works
|
||||||
|
- Verify proper modal appearance/styling in both light and dark themes
|
||||||
|
|
||||||
|
### Share Modal
|
||||||
|
|
||||||
|
- Open and close using the "Share" button
|
||||||
|
- Verify the URL is generated correctly
|
||||||
|
- Test the copy button
|
||||||
|
- Check that social sharing buttons display correctly
|
||||||
|
- Verify proper styling in both light and dark themes
|
||||||
|
- Test "Copied to clipboard" tooltip functionality
|
||||||
|
|
||||||
|
### Load/Save Modal
|
||||||
|
|
||||||
|
- Open and close using "Save" or "Load" options
|
||||||
|
- Test tab navigation between sections (Examples, Browser-local storage, etc.)
|
||||||
|
- Verify save functionality to browser storage
|
||||||
|
- Test loading from browser storage
|
||||||
|
- Check proper styling/layout in both light and dark themes
|
||||||
|
|
||||||
|
### Compiler Picker Modal
|
||||||
|
|
||||||
|
- Open using the popout button next to a compiler selector
|
||||||
|
- Test filter functionality (architecture, compiler type, search)
|
||||||
|
- Verify compiler selection works
|
||||||
|
- Check proper styling in both light and dark themes
|
||||||
|
|
||||||
|
### Other Modals
|
||||||
|
|
||||||
|
- Test confirmation dialogs (alert.ts)
|
||||||
|
- Test library selection modal
|
||||||
|
- Test compiler overrides modal
|
||||||
|
- Test runtime tools modal
|
||||||
|
- Test templates modal
|
||||||
|
- Verify proper styling in both light and dark themes
|
||||||
|
|
||||||
|
## Dropdown Components
|
||||||
|
|
||||||
|
### Main Navigation Dropdowns
|
||||||
|
|
||||||
|
- Test "More" dropdown menu (all items work and have proper styling)
|
||||||
|
- Test "Other" dropdown menu (all items work and have proper styling)
|
||||||
|
- Verify dropdowns are properly positioned (not clipped)
|
||||||
|
- Test on different screen sizes to ensure responsive behavior
|
||||||
|
|
||||||
|
### Compiler Option Dropdowns
|
||||||
|
|
||||||
|
- Test filter dropdowns in compiler pane
|
||||||
|
- Test "Add new..." dropdown
|
||||||
|
- Test "Add tool..." dropdown
|
||||||
|
- Test popular arguments dropdown
|
||||||
|
- Verify proper positioning, especially for dropdowns at the right edge of the screen
|
||||||
|
|
||||||
|
### Editor Dropdowns
|
||||||
|
|
||||||
|
- Test language selector dropdown
|
||||||
|
- Test font size dropdown
|
||||||
|
- Verify proper styling and positioning
|
||||||
|
|
||||||
|
### TomSelect Dropdowns
|
||||||
|
|
||||||
|
- Test compiler selectors
|
||||||
|
- Test library version selectors
|
||||||
|
- Verify dropdown arrows appear correctly
|
||||||
|
- Verify dropdown items are styled correctly
|
||||||
|
|
||||||
|
## Toast/Alert Components
|
||||||
|
|
||||||
|
### Alert Notifications
|
||||||
|
|
||||||
|
- Trigger various notifications (info, warning, error)
|
||||||
|
- Verify proper styling
|
||||||
|
- Test auto-dismiss functionality
|
||||||
|
- Check that close button works
|
||||||
|
- Test stacking behavior of multiple notifications
|
||||||
|
|
||||||
|
### Alert Dialogs
|
||||||
|
|
||||||
|
- Test info/warning/error alert dialogs (using the Alert class)
|
||||||
|
- Verify proper styling and positioning
|
||||||
|
- Check button functionality within dialogs
|
||||||
|
|
||||||
|
## Popover/Tooltip Components
|
||||||
|
|
||||||
|
### Tooltips
|
||||||
|
|
||||||
|
- Hover over various buttons with tooltips (toolbar buttons, share button, etc.)
|
||||||
|
- Verify tooltip text appears correctly
|
||||||
|
- Check tooltip positioning (above/below/left/right of trigger)
|
||||||
|
- Verify proper styling in both light and dark themes
|
||||||
|
|
||||||
|
### Popovers
|
||||||
|
|
||||||
|
- Trigger popovers on compiler info
|
||||||
|
- Check popover content displays correctly
|
||||||
|
- Verify popover positioning
|
||||||
|
- Test dismissal by clicking outside
|
||||||
|
- Verify proper styling in both light and dark themes
|
||||||
|
|
||||||
|
## Card Components
|
||||||
|
|
||||||
|
- Check card styling in modals (Settings, Load/Save, etc.)
|
||||||
|
- Verify tab navigation within card headers
|
||||||
|
- Test card body content layout
|
||||||
|
- Check responsive behavior on different screen sizes
|
||||||
|
|
||||||
|
## Button Group Components
|
||||||
|
|
||||||
|
### Toolbar Button Groups
|
||||||
|
|
||||||
|
- Test button groups in compiler pane toolbar
|
||||||
|
- Test button groups in editor pane toolbar
|
||||||
|
- Verify proper alignment and styling
|
||||||
|
- Check dropdown buttons within button groups
|
||||||
|
|
||||||
|
### Other Button Groups
|
||||||
|
|
||||||
|
- Test font size button group
|
||||||
|
- Test bottom bar button groups
|
||||||
|
- Verify proper styling in both light and dark themes
|
||||||
|
|
||||||
|
## Collapse Components
|
||||||
|
|
||||||
|
- Test mobile view hamburger menu
|
||||||
|
- Verify menu expands/collapses correctly
|
||||||
|
- Check that all menu items are accessible in collapsed mode
|
||||||
|
|
||||||
|
## Specialized Views
|
||||||
|
|
||||||
|
### Conformance View
|
||||||
|
|
||||||
|
- Test compiler selectors and options
|
||||||
|
- Verify results display correctly
|
||||||
|
- Test the "add compiler" functionality
|
||||||
|
- Verify that compilers can be added and removed
|
||||||
|
- Check that conformance testing works end-to-end
|
||||||
|
|
||||||
|
### Tree View (IDE Mode)
|
||||||
|
|
||||||
|
- Check tree structure and file display
|
||||||
|
- Test right-click menus and dropdowns
|
||||||
|
- Verify file manipulation controls
|
||||||
|
|
||||||
|
### Visualization Components
|
||||||
|
|
||||||
|
- Test CFG view rendering and controls
|
||||||
|
- Check opt pipeline viewer
|
||||||
|
- Verify AST view
|
||||||
|
|
||||||
|
### Sponsor Window
|
||||||
|
|
||||||
|
- Check sponsor list display
|
||||||
|
- Verify modal dialog appearance and functionality
|
||||||
|
|
||||||
|
## Form Components
|
||||||
|
|
||||||
|
- Verify form control styling (inputs, selects, checkboxes)
|
||||||
|
- Test input groups with buttons
|
||||||
|
- Check validation states
|
||||||
|
|
||||||
|
## Responsive Behavior
|
||||||
|
|
||||||
|
- Test at various viewport sizes
|
||||||
|
- Verify mobile menu functionality
|
||||||
|
- Check input group stacking behavior
|
||||||
|
|
||||||
|
## Runtime Tool Integration
|
||||||
|
|
||||||
|
### Runtime Tools
|
||||||
|
|
||||||
|
- Open the runtime tools window from compiler pane
|
||||||
|
- Change settings and click outside the modal to close
|
||||||
|
- Verify settings are properly saved
|
||||||
|
- Test with multiple runtime tool options
|
||||||
|
- Verify event handling properly handles modal opening/closing
|
||||||
|
|
||||||
|
### Emulation Features
|
||||||
|
|
||||||
|
- Test BBC emulation by clicking emulator links
|
||||||
|
- Check Z80 emulation features (e.g. https://godbolt.org/z/qnE7jhnvc)
|
||||||
|
- Verify emulator modals open properly
|
||||||
|
- Test interaction between emulator windows and the main interface
|
||||||
|
|
||||||
|
## Diff View
|
||||||
|
|
||||||
|
- Test changing compilers in both left and right panes
|
||||||
|
- Verify backgrounds remain themed correctly in dark mode
|
||||||
|
- Check that the diff view layout is correct (no excessive height)
|
||||||
|
- Confirm that input groups and buttons are properly sized
|
||||||
|
- Test different diff view types (Assembly, Compiler output, etc.)
|
||||||
|
|
||||||
|
## TomSelect and Input Components
|
||||||
|
|
||||||
|
### Compiler Selection Dropdowns
|
||||||
|
|
||||||
|
- Verify long compiler names display properly without excessive wrapping
|
||||||
|
- Check that dropdowns expand to fit compiler names rather than wrapping text
|
||||||
|
- Test the flex-grow behavior of dropdown elements
|
||||||
|
- Check the alignment of the popout button on all dropdowns
|
||||||
|
- Verify border colors in dark themes are appropriate
|
||||||
|
|
||||||
|
### Placeholder Text
|
||||||
|
|
||||||
|
- Check visibility and contrast of placeholder text in all input fields
|
||||||
|
- Specifically test "Compiler options" field visibility
|
||||||
|
- Verify that all placeholder text is readable in both light and dark themes
|
||||||
|
|
||||||
|
## Library Components
|
||||||
|
|
||||||
|
### Library Menu
|
||||||
|
|
||||||
|
- Check dropdown colors and layout
|
||||||
|
- Verify all library functionality works correctly
|
||||||
|
- Test adding and removing libraries
|
||||||
|
- Check library version selection
|
||||||
|
|
||||||
|
## History View
|
||||||
|
|
||||||
|
- Verify the history view populates correctly when clicking radio buttons
|
||||||
|
- Test all history functions (load, delete, etc.)
|
||||||
|
|
||||||
|
## General Testing
|
||||||
|
|
||||||
|
- Check pixel-perfect alignment of elements (compare with live site)
|
||||||
|
- Test all components for unexpected behavioral differences
|
||||||
|
- Verify theme switching works correctly for all components
|
||||||
|
- Test cross-browser compatibility (at least Firefox and Chrome)
|
||||||
|
- Check accessibility features (tab navigation, screen reader support)
|
||||||
@@ -92,7 +92,7 @@ async function generateScreenshot(url: string, output_path: string, settings, wi
|
|||||||
}, settings);
|
}, settings);
|
||||||
await page.goto(url);
|
await page.goto(url);
|
||||||
//await sleep(2000);
|
//await sleep(2000);
|
||||||
//await page.click(".modal.show button.btn.btn-outline-primary[data-dismiss=modal]");
|
//await page.click(".modal.show button.btn.btn-outline-primary[data-bs-dismiss=modal]");
|
||||||
//await sleep(5000);
|
//await sleep(5000);
|
||||||
//await page.click("#simplecook .btn.btn-primary.btn-sm.cook-do-consent");
|
//await page.click("#simplecook .btn.btn-primary.btn-sm.cook-do-consent");
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
|
|||||||
25
package-lock.json
generated
25
package-lock.json
generated
@@ -18,11 +18,12 @@
|
|||||||
"@flatten-js/interval-tree": "^1.1.3",
|
"@flatten-js/interval-tree": "^1.1.3",
|
||||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||||
"@orchidjs/sifter": "^1.1.0",
|
"@orchidjs/sifter": "^1.1.0",
|
||||||
|
"@popperjs/core": "^2.11.8",
|
||||||
"@sentry/browser": "^7.120.3",
|
"@sentry/browser": "^7.120.3",
|
||||||
"@sentry/node": "^7.120.3",
|
"@sentry/node": "^7.120.3",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
"big-integer": "^1.6.52",
|
"big-integer": "^1.6.52",
|
||||||
"bootstrap": "^4.6.2",
|
"bootstrap": "^5.3.5",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"chart.js": "^4.4.9",
|
"chart.js": "^4.4.9",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
@@ -48,7 +49,6 @@
|
|||||||
"nopt": "^8.1.0",
|
"nopt": "^8.1.0",
|
||||||
"p-queue": "^8.1.0",
|
"p-queue": "^8.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"popper.js": "^1.16.1",
|
|
||||||
"profanities": "^3.0.1",
|
"profanities": "^3.0.1",
|
||||||
"prom-client": "^15.1.3",
|
"prom-client": "^15.1.3",
|
||||||
"pug": "^3.0.3",
|
"pug": "^3.0.3",
|
||||||
@@ -3135,7 +3135,6 @@
|
|||||||
"version": "2.11.8",
|
"version": "2.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -5773,9 +5772,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/bootstrap": {
|
"node_modules/bootstrap": {
|
||||||
"version": "4.6.2",
|
"version": "5.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.5.tgz",
|
||||||
"integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==",
|
"integrity": "sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -5788,8 +5787,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"jquery": "1.9.1 - 3",
|
"@popperjs/core": "^2.11.8"
|
||||||
"popper.js": "^1.16.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bowser": {
|
"node_modules/bowser": {
|
||||||
@@ -10767,17 +10765,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/popper.js": {
|
|
||||||
"version": "1.16.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
|
||||||
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
|
|
||||||
"deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/popperjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.3",
|
"version": "8.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"@sentry/node": "^7.120.3",
|
"@sentry/node": "^7.120.3",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
"big-integer": "^1.6.52",
|
"big-integer": "^1.6.52",
|
||||||
"bootstrap": "^4.6.2",
|
"bootstrap": "^5.3.5",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"chart.js": "^4.4.9",
|
"chart.js": "^4.4.9",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"nopt": "^8.1.0",
|
"nopt": "^8.1.0",
|
||||||
"p-queue": "^8.1.0",
|
"p-queue": "^8.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"popper.js": "^1.16.1",
|
"@popperjs/core": "^2.11.8",
|
||||||
"profanities": "^3.0.1",
|
"profanities": "^3.0.1",
|
||||||
"prom-client": "^15.1.3",
|
"prom-client": "^15.1.3",
|
||||||
"pug": "^3.0.3",
|
"pug": "^3.0.3",
|
||||||
|
|||||||
471
static/bootstrap-utils.ts
Normal file
471
static/bootstrap-utils.ts
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
// Copyright (c) 2025, Compiler Explorer Authors
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TEMPORARY COMPATIBILITY LAYER
|
||||||
|
*
|
||||||
|
* This module provides utilities to help transition from Bootstrap 4's jQuery-based API
|
||||||
|
* to Bootstrap 5's vanilla JavaScript API. This is intended as a temporary solution
|
||||||
|
* during the migration from Bootstrap 4 to 5 and should be removed once the migration
|
||||||
|
* is complete.
|
||||||
|
*
|
||||||
|
* The goal is to minimize changes throughout the codebase by centralizing the Bootstrap
|
||||||
|
* API changes in this file, while still allowing for gradual migration to direct API calls.
|
||||||
|
*
|
||||||
|
* @deprecated This module should be removed after the Bootstrap 5 migration is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
import 'bootstrap';
|
||||||
|
import {Collapse, Dropdown, Modal, Popover, Tab, Toast, Tooltip} from 'bootstrap';
|
||||||
|
|
||||||
|
// Private event listener tracking map
|
||||||
|
const eventListenerMap = new WeakMap<HTMLElement, Map<string, EventListener>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get an HTMLElement from various input types
|
||||||
|
* @param elementOrSelector Element, jQuery object, or selector
|
||||||
|
* @returns HTMLElement or null
|
||||||
|
*/
|
||||||
|
function getElement(elementOrSelector: string | HTMLElement | JQuery): HTMLElement | null {
|
||||||
|
if (!elementOrSelector) return null;
|
||||||
|
|
||||||
|
if (typeof elementOrSelector === 'string') {
|
||||||
|
return document.querySelector(elementOrSelector as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementOrSelector instanceof HTMLElement) {
|
||||||
|
return elementOrSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementOrSelector instanceof $) {
|
||||||
|
return (elementOrSelector as JQuery)[0] as HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private helper that sets an event handler on a single DOM element
|
||||||
|
* Handles the removal of existing handlers and tracking of the new one
|
||||||
|
*
|
||||||
|
* @param domElement The DOM element to attach the event to
|
||||||
|
* @param eventName The event name (e.g., 'hidden.bs.modal', 'shown.bs.modal', 'click', etc.)
|
||||||
|
* @param handler The event handler function
|
||||||
|
*/
|
||||||
|
function setDomElementEventHandler(domElement: HTMLElement, eventName: string, handler: (event: Event) => void): void {
|
||||||
|
// Initialize nested map structure if needed
|
||||||
|
if (!eventListenerMap.has(domElement)) {
|
||||||
|
eventListenerMap.set(domElement, new Map());
|
||||||
|
}
|
||||||
|
|
||||||
|
const elementEvents = eventListenerMap.get(domElement)!;
|
||||||
|
|
||||||
|
// Remove existing handler if present
|
||||||
|
if (elementEvents.has(eventName)) {
|
||||||
|
const oldHandler = elementEvents.get(eventName)!;
|
||||||
|
domElement.removeEventListener(eventName, oldHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store and add new handler
|
||||||
|
elementEvents.set(eventName, handler);
|
||||||
|
domElement.addEventListener(eventName, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an event handler on element(s), removing any previous handler for the same event
|
||||||
|
* Similar to jQuery's off().on() pattern
|
||||||
|
* Works with both single elements and jQuery collections with multiple elements
|
||||||
|
*
|
||||||
|
* @param element The element(s) or jQuery object to attach the event to
|
||||||
|
* @param eventName The event name (e.g., 'hidden.bs.modal', 'shown.bs.modal', 'click', etc.)
|
||||||
|
* @param handler The event handler function
|
||||||
|
*/
|
||||||
|
export function setElementEventHandler(
|
||||||
|
element: JQuery<HTMLElement> | HTMLElement,
|
||||||
|
eventName: string,
|
||||||
|
handler: (event: Event) => void,
|
||||||
|
): void {
|
||||||
|
// If jQuery object with potentially multiple elements
|
||||||
|
if (!(element instanceof HTMLElement)) {
|
||||||
|
// Loop through all elements in the jQuery collection
|
||||||
|
element.each((_index, domElement) => {
|
||||||
|
setDomElementEventHandler(domElement, eventName, handler);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise it's a single DOM element
|
||||||
|
setDomElementEventHandler(element, eventName, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a modal
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
* @param options Modal options
|
||||||
|
* @returns Modal instance
|
||||||
|
* @throws Error if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initModal(elementOrSelector: string | HTMLElement | JQuery, options?: Partial<Modal.Options>): Modal {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for modal: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Modal(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a modal if the element exists, returning null otherwise
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
* @param options Modal options
|
||||||
|
* @returns Modal instance or null if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initModalIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Modal.Options>,
|
||||||
|
): Modal | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Modal(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing modal instance for an element
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
* @returns Existing modal instance or null if not found
|
||||||
|
*/
|
||||||
|
export function getModalInstance(elementOrSelector: string | HTMLElement | JQuery): Modal | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return Modal.getInstance(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a modal
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
* @param relatedTarget Optional related target element
|
||||||
|
*/
|
||||||
|
export function showModal(elementOrSelector: string | HTMLElement | JQuery, relatedTarget?: HTMLElement): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const modal = Modal.getInstance(element) || new Modal(element);
|
||||||
|
modal.show(relatedTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide a modal
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
*/
|
||||||
|
export function hideModal(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const modal = Modal.getInstance(element);
|
||||||
|
if (modal) modal.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a toast
|
||||||
|
* @param elementOrSelector Element or selector for the toast
|
||||||
|
* @param options Toast options
|
||||||
|
* @returns Toast instance
|
||||||
|
*/
|
||||||
|
export function initToast(elementOrSelector: string | HTMLElement | JQuery, options?: Partial<Toast.Options>): Toast {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for toast: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Toast(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a toast if the element exists
|
||||||
|
* @param elementOrSelector Element or selector for the toast
|
||||||
|
* @param options Toast options
|
||||||
|
* @returns Toast instance or null if element doesn't exist
|
||||||
|
*/
|
||||||
|
export function initToastIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Toast.Options>,
|
||||||
|
): Toast | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Toast(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a toast
|
||||||
|
* @param elementOrSelector Element or selector for the toast
|
||||||
|
*/
|
||||||
|
export function showToast(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const toast = Toast.getInstance(element) || new Toast(element);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide a toast
|
||||||
|
* @param elementOrSelector Element or selector for the toast
|
||||||
|
*/
|
||||||
|
export function hideToast(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const toast = Toast.getInstance(element);
|
||||||
|
if (toast) toast.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a dropdown
|
||||||
|
* @param elementOrSelector Element or selector for the dropdown
|
||||||
|
* @param options Dropdown options
|
||||||
|
* @returns Dropdown instance
|
||||||
|
* @throws Error if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initDropdown(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Dropdown.Options>,
|
||||||
|
): Dropdown {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for dropdown: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Dropdown(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a dropdown if the element exists, returning null otherwise
|
||||||
|
* @param elementOrSelector Element or selector for the dropdown
|
||||||
|
* @param options Dropdown options
|
||||||
|
* @returns Dropdown instance or null if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initDropdownIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Dropdown.Options>,
|
||||||
|
): Dropdown | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Dropdown(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing dropdown instance for an element
|
||||||
|
* @param elementOrSelector Element or selector for the dropdown
|
||||||
|
* @returns Existing dropdown instance or null if not found
|
||||||
|
*/
|
||||||
|
export function getDropdownInstance(elementOrSelector: string | HTMLElement | JQuery): Dropdown | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return Dropdown.getInstance(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a dropdown
|
||||||
|
* @param elementOrSelector Element or selector for the dropdown
|
||||||
|
*/
|
||||||
|
export function showDropdown(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const dropdown = Dropdown.getInstance(element) || new Dropdown(element);
|
||||||
|
dropdown.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide a dropdown
|
||||||
|
* @param elementOrSelector Element or selector for the dropdown
|
||||||
|
*/
|
||||||
|
export function hideDropdown(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const dropdown = Dropdown.getInstance(element);
|
||||||
|
if (dropdown) dropdown.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a tooltip
|
||||||
|
* @param elementOrSelector Element or selector for the tooltip
|
||||||
|
* @param options Tooltip options
|
||||||
|
* @returns Tooltip instance
|
||||||
|
*/
|
||||||
|
export function initTooltip(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Tooltip.Options>,
|
||||||
|
): Tooltip {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for tooltip: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Tooltip(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a tooltip if the element exists
|
||||||
|
* @param elementOrSelector Element or selector for the tooltip
|
||||||
|
* @param options Tooltip options
|
||||||
|
* @returns Tooltip instance or null if element doesn't exist
|
||||||
|
*/
|
||||||
|
export function initTooltipIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Tooltip.Options>,
|
||||||
|
): Tooltip | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Tooltip(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a popover
|
||||||
|
* @param elementOrSelector Element or selector for the popover
|
||||||
|
* @param options Popover options
|
||||||
|
* @returns Popover instance
|
||||||
|
* @throws Error if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initPopover(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Popover.Options>,
|
||||||
|
): Popover {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for popover: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Popover(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a popover if the element exists, returning null otherwise
|
||||||
|
* @param elementOrSelector Element or selector for the popover
|
||||||
|
* @param options Popover options
|
||||||
|
* @returns Popover instance or null if the element cannot be found
|
||||||
|
*/
|
||||||
|
export function initPopoverIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Popover.Options>,
|
||||||
|
): Popover | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Popover(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing popover instance for an element
|
||||||
|
* @param elementOrSelector Element or selector for the popover
|
||||||
|
* @returns Existing popover instance or null if not found
|
||||||
|
*/
|
||||||
|
export function getPopoverInstance(elementOrSelector: string | HTMLElement | JQuery): Popover | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return Popover.getInstance(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a tab
|
||||||
|
* @param elementOrSelector Element or selector for the tab
|
||||||
|
* @returns Tab instance
|
||||||
|
*/
|
||||||
|
export function initTab(elementOrSelector: string | HTMLElement | JQuery): Tab {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for tab: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Tab(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a tab if the element exists
|
||||||
|
* @param elementOrSelector Element or selector for the tab
|
||||||
|
* @returns Tab instance or null if element doesn't exist
|
||||||
|
*/
|
||||||
|
export function initTabIfExists(elementOrSelector: string | HTMLElement | JQuery): Tab | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Tab(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a collapse
|
||||||
|
* @param elementOrSelector Element or selector for the collapse
|
||||||
|
* @param options Collapse options
|
||||||
|
* @returns Collapse instance
|
||||||
|
*/
|
||||||
|
export function initCollapse(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Collapse.Options>,
|
||||||
|
): Collapse {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) throw new Error(`Failed to find element for collapse: ${elementOrSelector}`);
|
||||||
|
|
||||||
|
return new Collapse(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a collapse if the element exists
|
||||||
|
* @param elementOrSelector Element or selector for the collapse
|
||||||
|
* @param options Collapse options
|
||||||
|
* @returns Collapse instance or null if element doesn't exist
|
||||||
|
*/
|
||||||
|
export function initCollapseIfExists(
|
||||||
|
elementOrSelector: string | HTMLElement | JQuery,
|
||||||
|
options?: Partial<Collapse.Options>,
|
||||||
|
): Collapse | null {
|
||||||
|
const element = getElement(elementOrSelector);
|
||||||
|
if (!element) return null;
|
||||||
|
|
||||||
|
return new Collapse(element, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide an existing popover if it exists
|
||||||
|
* @param elementOrSelector Element or selector for the popover
|
||||||
|
*/
|
||||||
|
export function hidePopover(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const popover = getPopoverInstance(elementOrSelector);
|
||||||
|
if (popover) popover.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an existing popover if it exists
|
||||||
|
* @param elementOrSelector Element or selector for the popover
|
||||||
|
*/
|
||||||
|
export function showPopover(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const popover = getPopoverInstance(elementOrSelector);
|
||||||
|
if (popover) popover.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an existing modal if it exists (uses existing instance only)
|
||||||
|
* @param elementOrSelector Element or selector for the modal
|
||||||
|
*/
|
||||||
|
export function showModalIfExists(elementOrSelector: string | HTMLElement | JQuery): void {
|
||||||
|
const modal = getModalInstance(elementOrSelector);
|
||||||
|
if (modal) modal.show();
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ import {SentryCapture, SetupSentry, setSentryLayout} from './sentry.js';
|
|||||||
SetupSentry();
|
SetupSentry();
|
||||||
|
|
||||||
import 'whatwg-fetch';
|
import 'whatwg-fetch';
|
||||||
import 'popper.js';
|
import '@popperjs/core';
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
@@ -62,6 +62,7 @@ import {ComponentConfig, EmptyCompilerState, StateWithId, StateWithLanguage} fro
|
|||||||
import {CompilerExplorerOptions} from './global.js';
|
import {CompilerExplorerOptions} from './global.js';
|
||||||
|
|
||||||
import * as utils from '../shared/common-utils.js';
|
import * as utils from '../shared/common-utils.js';
|
||||||
|
import * as BootstrapUtils from './bootstrap-utils.js';
|
||||||
import {ParseFiltersAndOutputOptions} from './features/filters.interfaces.js';
|
import {ParseFiltersAndOutputOptions} from './features/filters.interfaces.js';
|
||||||
import {localStorage, sessionThenLocalStorage} from './local.js';
|
import {localStorage, sessionThenLocalStorage} from './local.js';
|
||||||
import {Printerinator} from './print-view.js';
|
import {Printerinator} from './print-view.js';
|
||||||
@@ -79,7 +80,7 @@ if (!window.PRODUCTION && !options.embedded) {
|
|||||||
//css
|
//css
|
||||||
require('bootstrap/dist/css/bootstrap.min.css');
|
require('bootstrap/dist/css/bootstrap.min.css');
|
||||||
require('golden-layout/src/css/goldenlayout-base.css');
|
require('golden-layout/src/css/goldenlayout-base.css');
|
||||||
require('tom-select/dist/css/tom-select.bootstrap4.css');
|
require('tom-select/dist/css/tom-select.bootstrap5.css');
|
||||||
require('./styles/colours.scss');
|
require('./styles/colours.scss');
|
||||||
require('./styles/explorer.scss');
|
require('./styles/explorer.scss');
|
||||||
|
|
||||||
@@ -225,7 +226,7 @@ function setupButtons(options: CompilerExplorerOptions, hub: Hub) {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#history').modal();
|
BootstrapUtils.showModal('#history');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#ui-apply-default-font-scale').on('click', () => {
|
$('#ui-apply-default-font-scale').on('click', () => {
|
||||||
@@ -530,7 +531,7 @@ function initShortlinkInfoButton() {
|
|||||||
buttonText.html('');
|
buttonText.html('');
|
||||||
|
|
||||||
const button = $('.shortlinkInfo');
|
const button = $('.shortlinkInfo');
|
||||||
button.popover({
|
BootstrapUtils.initPopover(button, {
|
||||||
html: true,
|
html: true,
|
||||||
title: 'Link created',
|
title: 'Link created',
|
||||||
content: formatISODate(dt, true),
|
content: formatISODate(dt, true),
|
||||||
@@ -677,11 +678,13 @@ function start() {
|
|||||||
setupButtons(options, hub);
|
setupButtons(options, hub);
|
||||||
}
|
}
|
||||||
|
|
||||||
const addDropdown = $('#addDropdown');
|
|
||||||
|
|
||||||
function setupAdd<C>(thing: JQuery, func: () => ComponentConfig<C>) {
|
function setupAdd<C>(thing: JQuery, func: () => ComponentConfig<C>) {
|
||||||
(layout.createDragSource(thing, func as any) as any)._dragListener.on('dragStart', () => {
|
(layout.createDragSource(thing, func as any) as any)._dragListener.on('dragStart', () => {
|
||||||
addDropdown.dropdown('toggle');
|
const addDropdown = unwrap(
|
||||||
|
BootstrapUtils.getDropdownInstance('#addDropdown'),
|
||||||
|
'Dropdown instance not found for #addDropdown',
|
||||||
|
);
|
||||||
|
addDropdown.toggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
thing.on('click', () => {
|
thing.on('click', () => {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ function ensureShownMessage(message: string, motdNode: JQuery) {
|
|||||||
motdNode.find('.content').html(message);
|
motdNode.find('.content').html(message);
|
||||||
motdNode.removeClass('d-none');
|
motdNode.removeClass('d-none');
|
||||||
motdNode
|
motdNode
|
||||||
.find('.close')
|
.find('.btn-close')
|
||||||
.on('click', () => {
|
.on('click', () => {
|
||||||
motdNode.addClass('d-none');
|
motdNode.addClass('d-none');
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
// This jQuery import needs to be here, because noscript.ts is a different entrypoint than the rest of the code.
|
// This jQuery import needs to be here, because noscript.ts is a different entrypoint than the rest of the code.
|
||||||
// See webpack.config.esm.ts -> entry for more details.
|
// See webpack.config.esm.ts -> entry for more details.
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import '@popperjs/core';
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
import 'popper.js';
|
|
||||||
|
|
||||||
import {Toggles} from './widgets/toggles.js';
|
import {Toggles} from './widgets/toggles.js';
|
||||||
import './styles/noscript.scss';
|
import './styles/noscript.scss';
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import * as fileSaver from 'file-saver';
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {Pane} from './pane.js';
|
import {Pane} from './pane.js';
|
||||||
|
|
||||||
import {Container} from 'golden-layout';
|
import {Container} from 'golden-layout';
|
||||||
@@ -281,7 +282,9 @@ export class Cfg extends Pane<CfgState> {
|
|||||||
if (this.tooltipOpen) {
|
if (this.tooltipOpen) {
|
||||||
if (!e.target.classList.contains('fold') && $(e.target).parents('.popover.in').length === 0) {
|
if (!e.target.classList.contains('fold') && $(e.target).parents('.popover.in').length === 0) {
|
||||||
this.tooltipOpen = false;
|
this.tooltipOpen = false;
|
||||||
$('.fold').popover('hide');
|
$('.fold').each((_, element) => {
|
||||||
|
BootstrapUtils.hidePopover(element);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -389,9 +392,10 @@ export class Cfg extends Pane<CfgState> {
|
|||||||
}" aria-describedby="wtf">⋯</span>`;
|
}" aria-describedby="wtf">⋯</span>`;
|
||||||
}
|
}
|
||||||
div.innerHTML = lines.join('<br/>');
|
div.innerHTML = lines.join('<br/>');
|
||||||
for (const fold of div.getElementsByClassName('fold')) {
|
for (const foldElement of div.getElementsByClassName('fold')) {
|
||||||
$(fold)
|
const fold = foldElement as HTMLElement;
|
||||||
.popover({
|
|
||||||
|
BootstrapUtils.initPopover(fold, {
|
||||||
content: unwrap(fold.getAttribute('data-extra')),
|
content: unwrap(fold.getAttribute('data-extra')),
|
||||||
html: true,
|
html: true,
|
||||||
placement: 'top',
|
placement: 'top',
|
||||||
@@ -401,11 +405,12 @@ export class Cfg extends Pane<CfgState> {
|
|||||||
'<h3 class="popover-header"></h3>' +
|
'<h3 class="popover-header"></h3>' +
|
||||||
'<div class="popover-body"></div>' +
|
'<div class="popover-body"></div>' +
|
||||||
'</div>',
|
'</div>',
|
||||||
})
|
});
|
||||||
.on('show.bs.popover', () => {
|
|
||||||
|
BootstrapUtils.setElementEventHandler(fold, 'show.bs.popover', () => {
|
||||||
this.tooltipOpen = true;
|
this.tooltipOpen = true;
|
||||||
})
|
});
|
||||||
.on('hide.bs.popover', () => {
|
BootstrapUtils.setElementEventHandler(fold, 'hide.bs.popover', () => {
|
||||||
this.tooltipOpen = false;
|
this.tooltipOpen = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -500,7 +505,11 @@ export class Cfg extends Pane<CfgState> {
|
|||||||
// Display the cfg for the specified function if it exists
|
// Display the cfg for the specified function if it exists
|
||||||
// This function sets this.state.selectedFunction if the input is non-null and valid
|
// This function sets this.state.selectedFunction if the input is non-null and valid
|
||||||
async selectFunction(name: string | null) {
|
async selectFunction(name: string | null) {
|
||||||
$('.fold').popover('dispose');
|
$('.fold').each((_, element) => {
|
||||||
|
const popover = BootstrapUtils.getPopoverInstance(element);
|
||||||
|
if (popover) popover.dispose();
|
||||||
|
// We need to dispose here, not just hide
|
||||||
|
});
|
||||||
this.blockContainer.innerHTML = '';
|
this.blockContainer.innerHTML = '';
|
||||||
this.svg.innerHTML = '';
|
this.svg.innerHTML = '';
|
||||||
this.estimatedPNGSize.innerHTML = '';
|
this.estimatedPNGSize.innerHTML = '';
|
||||||
@@ -669,7 +678,9 @@ export class Cfg extends Pane<CfgState> {
|
|||||||
const topBarHeight = utils.updateAndCalcTopBarHeight(this.domRoot, this.topBar, this.hideable);
|
const topBarHeight = utils.updateAndCalcTopBarHeight(this.domRoot, this.topBar, this.hideable);
|
||||||
this.graphContainer.style.width = `${unwrap(this.domRoot.width())}px`;
|
this.graphContainer.style.width = `${unwrap(this.domRoot.width())}px`;
|
||||||
this.graphContainer.style.height = `${unwrap(this.domRoot.height()) - topBarHeight}px`;
|
this.graphContainer.style.height = `${unwrap(this.domRoot.height()) - topBarHeight}px`;
|
||||||
$('.fold').popover('hide');
|
$('.fold').each((_, element) => {
|
||||||
|
BootstrapUtils.hidePopover(element);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import {
|
|||||||
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
||||||
import {ResultLine} from '../../types/resultline/resultline.interfaces.js';
|
import {ResultLine} from '../../types/resultline/resultline.interfaces.js';
|
||||||
import {getAssemblyDocumentation} from '../api/api.js';
|
import {getAssemblyDocumentation} from '../api/api.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import * as codeLensHandler from '../codelens-handler.js';
|
import * as codeLensHandler from '../codelens-handler.js';
|
||||||
import * as colour from '../colour.js';
|
import * as colour from '../colour.js';
|
||||||
import {OptPipelineBackendOptions} from '../compilation/opt-pipeline-output.interfaces.js';
|
import {OptPipelineBackendOptions} from '../compilation/opt-pipeline-output.interfaces.js';
|
||||||
@@ -678,7 +679,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
|
|
||||||
const newPaneDropdown = this.domRoot.find('.new-pane-dropdown');
|
const newPaneDropdown = this.domRoot.find('.new-pane-dropdown');
|
||||||
const hidePaneAdder = () => {
|
const hidePaneAdder = () => {
|
||||||
newPaneDropdown.dropdown('hide');
|
BootstrapUtils.hideDropdown(newPaneDropdown);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note that the .d.ts file lies in more than 1 way!
|
// Note that the .d.ts file lies in more than 1 way!
|
||||||
@@ -729,7 +730,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
.createDragSource(this.flagsButton, createFlagsView as any)
|
.createDragSource(this.flagsButton, createFlagsView as any)
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
._dragListener.on('dragStart', () => popularArgumentsMenu.dropdown('hide'));
|
._dragListener.on('dragStart', () => BootstrapUtils.hideDropdown(popularArgumentsMenu));
|
||||||
|
|
||||||
this.flagsButton.on('click', () => {
|
this.flagsButton.on('click', () => {
|
||||||
const insertPoint =
|
const insertPoint =
|
||||||
@@ -1868,7 +1869,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
dismissTime: 10000,
|
dismissTime: 10000,
|
||||||
onBeforeShow: elem => {
|
onBeforeShow: elem => {
|
||||||
elem.find('#miracle_emulink').on('click', () => {
|
elem.find('#miracle_emulink').on('click', () => {
|
||||||
dialog.modal();
|
BootstrapUtils.showModal(dialog);
|
||||||
|
|
||||||
const miracleMenuFrame = dialog.find('#miracleemuframe')[0];
|
const miracleMenuFrame = dialog.find('#miracleemuframe')[0];
|
||||||
assert(miracleMenuFrame instanceof HTMLIFrameElement);
|
assert(miracleMenuFrame instanceof HTMLIFrameElement);
|
||||||
@@ -1896,7 +1897,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
dismissTime: 10000,
|
dismissTime: 10000,
|
||||||
onBeforeShow: elem => {
|
onBeforeShow: elem => {
|
||||||
elem.find('#jsspeccy_emulink').on('click', () => {
|
elem.find('#jsspeccy_emulink').on('click', () => {
|
||||||
dialog.modal();
|
BootstrapUtils.showModal(dialog);
|
||||||
|
|
||||||
const speccyemuframe = dialog.find('#speccyemuframe')[0];
|
const speccyemuframe = dialog.find('#speccyemuframe')[0];
|
||||||
assert(speccyemuframe instanceof HTMLIFrameElement);
|
assert(speccyemuframe instanceof HTMLIFrameElement);
|
||||||
@@ -1923,7 +1924,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
dismissTime: 10000,
|
dismissTime: 10000,
|
||||||
onBeforeShow: elem => {
|
onBeforeShow: elem => {
|
||||||
elem.find('#emulink').on('click', () => {
|
elem.find('#emulink').on('click', () => {
|
||||||
dialog.modal();
|
BootstrapUtils.showModal(dialog);
|
||||||
|
|
||||||
const jsbeebemuframe = dialog.find('#jsbeebemuframe')[0];
|
const jsbeebemuframe = dialog.find('#jsbeebemuframe')[0];
|
||||||
assert(jsbeebemuframe instanceof HTMLIFrameElement);
|
assert(jsbeebemuframe instanceof HTMLIFrameElement);
|
||||||
@@ -1950,7 +1951,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
dismissTime: 10000,
|
dismissTime: 10000,
|
||||||
onBeforeShow: elem => {
|
onBeforeShow: elem => {
|
||||||
elem.find('#emulink').on('click', () => {
|
elem.find('#emulink').on('click', () => {
|
||||||
dialog.modal();
|
BootstrapUtils.showModal(dialog);
|
||||||
|
|
||||||
const jsnesemuframe = dialog.find('#jsnesemuframe')[0];
|
const jsnesemuframe = dialog.find('#jsnesemuframe')[0];
|
||||||
assert(jsnesemuframe instanceof HTMLIFrameElement);
|
assert(jsnesemuframe instanceof HTMLIFrameElement);
|
||||||
@@ -2683,7 +2684,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
initToolButtons(): void {
|
initToolButtons(): void {
|
||||||
this.toolsMenu = this.domRoot.find('.new-tool-dropdown');
|
this.toolsMenu = this.domRoot.find('.new-tool-dropdown');
|
||||||
const hideToolDropdown = () => {
|
const hideToolDropdown = () => {
|
||||||
this.toolsMenu?.dropdown('hide');
|
if (this.toolsMenu) BootstrapUtils.hideDropdown(this.toolsMenu);
|
||||||
};
|
};
|
||||||
this.toolsMenu.empty();
|
this.toolsMenu.empty();
|
||||||
|
|
||||||
@@ -3053,14 +3054,14 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
this.prependOptions.has(target as unknown as Element).length === 0 &&
|
this.prependOptions.has(target as unknown as Element).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
)
|
)
|
||||||
this.prependOptions.popover('hide');
|
BootstrapUtils.hidePopover(this.prependOptions);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!target.is(this.fullCompilerName) &&
|
!target.is(this.fullCompilerName) &&
|
||||||
this.fullCompilerName.has(target as unknown as Element).length === 0 &&
|
this.fullCompilerName.has(target as unknown as Element).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
)
|
)
|
||||||
this.fullCompilerName.popover('hide');
|
BootstrapUtils.hidePopover(this.fullCompilerName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3104,7 +3105,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
// Dismiss the popover on escape.
|
// Dismiss the popover on escape.
|
||||||
$(document).on('keyup.editable', e => {
|
$(document).on('keyup.editable', e => {
|
||||||
if (e.which === 27) {
|
if (e.which === 27) {
|
||||||
this.libsButton.popover('hide');
|
BootstrapUtils.hidePopover(this.libsButton);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3118,7 +3119,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
elem.has(target as unknown as Element).length === 0 &&
|
elem.has(target as unknown as Element).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
) {
|
) {
|
||||||
elem.popover('hide');
|
BootstrapUtils.hidePopover(elem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -3460,8 +3461,13 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
|
|||||||
setCompilationOptionsPopover(content: string | null, warnings: string[]): void {
|
setCompilationOptionsPopover(content: string | null, warnings: string[]): void {
|
||||||
const infoLine =
|
const infoLine =
|
||||||
'<div class="compiler-arg-warning info">You can configure icon animations in Settings>Compilation</div>\n';
|
'<div class="compiler-arg-warning info">You can configure icon animations in Settings>Compilation</div>\n';
|
||||||
this.prependOptions.popover('dispose');
|
|
||||||
this.prependOptions.popover({
|
// Dispose any existing popover
|
||||||
|
const existingPopover = BootstrapUtils.getPopoverInstance(this.prependOptions);
|
||||||
|
if (existingPopover) existingPopover.dispose();
|
||||||
|
|
||||||
|
// Create new popover
|
||||||
|
BootstrapUtils.initPopover(this.prependOptions, {
|
||||||
content:
|
content:
|
||||||
warnings.map(w => `<div class="compiler-arg-warning">${w}</div>`).join('\n') +
|
warnings.map(w => `<div class="compiler-arg-warning">${w}</div>`).join('\n') +
|
||||||
'\n' +
|
'\n' +
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {escapeHTML, unique} from '../../shared/common-utils.js';
|
|||||||
import {CompilationResult} from '../../types/compilation/compilation.interfaces.js';
|
import {CompilationResult} from '../../types/compilation/compilation.interfaces.js';
|
||||||
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
||||||
import {unwrapString} from '../assert.js';
|
import {unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {CompilationStatus} from '../compiler-service.interfaces.js';
|
import {CompilationStatus} from '../compiler-service.interfaces.js';
|
||||||
import {CompilerService} from '../compiler-service.js';
|
import {CompilerService} from '../compiler-service.js';
|
||||||
import * as Components from '../components.js';
|
import * as Components from '../components.js';
|
||||||
@@ -100,7 +101,7 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
// Dismiss the popover on escape.
|
// Dismiss the popover on escape.
|
||||||
$(document).on('keyup.editable', e => {
|
$(document).on('keyup.editable', e => {
|
||||||
if (e.which === 27) {
|
if (e.which === 27) {
|
||||||
this.libsButton.popover('hide');
|
BootstrapUtils.hidePopover(this.libsButton);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
elem.has(target as unknown as Element).length === 0 &&
|
elem.has(target as unknown as Element).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
) {
|
) {
|
||||||
elem.popover('hide');
|
BootstrapUtils.hidePopover(elem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -150,7 +151,7 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
this.conformanceContentRoot = this.domRoot.find('.conformance-wrapper');
|
this.conformanceContentRoot = this.domRoot.find('.conformance-wrapper');
|
||||||
this.selectorList = this.domRoot.find('.compiler-list');
|
this.selectorList = this.domRoot.find('.compiler-list');
|
||||||
this.addCompilerButton = this.domRoot.find('.add-compiler');
|
this.addCompilerButton = this.domRoot.find('.add-compiler');
|
||||||
this.selectorTemplate = $('#compiler-selector').find('.form-row');
|
this.selectorTemplate = $('#compiler-selector').find('.row');
|
||||||
this.topBar = this.domRoot.find('.top-bar');
|
this.topBar = this.domRoot.find('.top-bar');
|
||||||
this.libsButton = this.topBar.find('.show-libs');
|
this.libsButton = this.topBar.find('.show-libs');
|
||||||
this.hideable = this.domRoot.find('.hideable');
|
this.hideable = this.domRoot.find('.hideable');
|
||||||
@@ -225,15 +226,11 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
.on('change', onOptionsChange)
|
.on('change', onOptionsChange)
|
||||||
.on('keyup', onOptionsChange);
|
.on('keyup', onOptionsChange);
|
||||||
|
|
||||||
newSelector
|
newSelector.find('.close-compiler').on('click', () => {
|
||||||
.find('.close')
|
|
||||||
.not('.extract-compiler')
|
|
||||||
.not('.copy-compiler')
|
|
||||||
.on('click', () => {
|
|
||||||
this.removeCompilerPicker(newCompilerEntry);
|
this.removeCompilerPicker(newCompilerEntry);
|
||||||
});
|
});
|
||||||
|
|
||||||
newSelector.find('.close.copy-compiler').on('click', () => {
|
newSelector.find('.copy-compiler').on('click', () => {
|
||||||
const config: AddCompilerPickerConfig = {
|
const config: AddCompilerPickerConfig = {
|
||||||
compilerId: newCompilerEntry.picker?.lastCompilerId ?? '',
|
compilerId: newCompilerEntry.picker?.lastCompilerId ?? '',
|
||||||
options: newCompilerEntry.optionsField?.val() || '',
|
options: newCompilerEntry.optionsField?.val() || '',
|
||||||
@@ -301,8 +298,11 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
): void {}
|
): void {}
|
||||||
|
|
||||||
setCompilationOptionsPopover(element: JQuery<HTMLElement> | null, content: string): void {
|
setCompilationOptionsPopover(element: JQuery<HTMLElement> | null, content: string): void {
|
||||||
element?.popover('dispose');
|
if (element) {
|
||||||
element?.popover({
|
const existingPopover = BootstrapUtils.getPopoverInstance(element);
|
||||||
|
if (existingPopover) existingPopover.dispose();
|
||||||
|
|
||||||
|
BootstrapUtils.initPopover(element, {
|
||||||
content: content || 'No options in use',
|
content: content || 'No options in use',
|
||||||
template:
|
template:
|
||||||
'<div class="popover' +
|
'<div class="popover' +
|
||||||
@@ -311,6 +311,7 @@ export class Conformance extends Pane<ConformanceViewState> {
|
|||||||
'<h3 class="popover-header"></h3><div class="popover-body"></div></div>',
|
'<h3 class="popover-header"></h3><div class="popover-body"></div></div>',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
removeCompilerPicker(compilerEntry: CompilerEntry): void {
|
removeCompilerPicker(compilerEntry: CompilerEntry): void {
|
||||||
this.compilerPickers = _.reject(this.compilerPickers, entry => compilerEntry.picker?.id === entry.picker?.id);
|
this.compilerPickers = _.reject(this.compilerPickers, entry => compilerEntry.picker?.id === entry.picker?.id);
|
||||||
|
|||||||
@@ -482,10 +482,7 @@ export class Diff extends MonacoPane<monaco.editor.IStandaloneDiffEditor, DiffSt
|
|||||||
) {
|
) {
|
||||||
if (!compiler) return;
|
if (!compiler) return;
|
||||||
options = options || '';
|
options = options || '';
|
||||||
let name = compiler.name + ' ' + options;
|
const name = compiler.name + ' ' + options;
|
||||||
// TODO: tomselect doesn't play nicely with CSS tricks for truncation; this is the best I can do
|
|
||||||
const maxLength = 30;
|
|
||||||
if (name.length > maxLength - 3) name = name.substring(0, maxLength - 3) + '...';
|
|
||||||
this.compilers[id] = {
|
this.compilers[id] = {
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import * as monaco from 'monaco-editor';
|
|||||||
import * as monacoVim from 'monaco-vim';
|
import * as monacoVim from 'monaco-vim';
|
||||||
import TomSelect from 'tom-select';
|
import TomSelect from 'tom-select';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import * as colour from '../colour.js';
|
import * as colour from '../colour.js';
|
||||||
import * as Components from '../components.js';
|
import * as Components from '../components.js';
|
||||||
import * as monacoConfig from '../monaco-config.js';
|
import * as monacoConfig from '../monaco-config.js';
|
||||||
@@ -472,7 +473,7 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
}
|
}
|
||||||
|
|
||||||
enableVim(): void {
|
enableVim(): void {
|
||||||
const statusElem = this.domRoot.find('#v-status')[0];
|
const statusElem = this.domRoot.find('.v-status')[0];
|
||||||
const vimMode = monacoVim.initVimMode(this.editor, statusElem);
|
const vimMode = monacoVim.initVimMode(this.editor, statusElem);
|
||||||
this.vimMode = vimMode;
|
this.vimMode = vimMode;
|
||||||
this.vimFlag.prop('class', 'btn btn-info');
|
this.vimFlag.prop('class', 'btn btn-info');
|
||||||
@@ -481,7 +482,7 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
|
|
||||||
disableVim(): void {
|
disableVim(): void {
|
||||||
this.vimMode.dispose();
|
this.vimMode.dispose();
|
||||||
this.domRoot.find('#v-status').html('');
|
this.domRoot.find('.v-status').html('');
|
||||||
this.vimFlag.prop('class', 'btn btn-light');
|
this.vimFlag.prop('class', 'btn btn-light');
|
||||||
(this.editor as any).vimInUse = false;
|
(this.editor as any).vimInUse = false;
|
||||||
}
|
}
|
||||||
@@ -520,8 +521,8 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
this.addExecutorButton = this.domRoot.find('.btn.add-executor');
|
this.addExecutorButton = this.domRoot.find('.btn.add-executor');
|
||||||
this.conformanceViewerButton = this.domRoot.find('.btn.conformance');
|
this.conformanceViewerButton = this.domRoot.find('.btn.conformance');
|
||||||
const addEditorButton = this.domRoot.find('.btn.add-editor');
|
const addEditorButton = this.domRoot.find('.btn.add-editor');
|
||||||
const toggleVimButton = this.domRoot.find('#vim-flag');
|
const toggleVimButton = this.domRoot.find('.vim-flag');
|
||||||
this.vimFlag = this.domRoot.find('#vim-flag');
|
this.vimFlag = this.domRoot.find('.vim-flag');
|
||||||
toggleVimButton.on('click', () => {
|
toggleVimButton.on('click', () => {
|
||||||
if ((this.editor as any).vimInUse) {
|
if ((this.editor as any).vimInUse) {
|
||||||
this.disableVim();
|
this.disableVim();
|
||||||
@@ -541,7 +542,7 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.languageInfoButton = this.domRoot.find('.language-info');
|
this.languageInfoButton = this.domRoot.find('.language-info');
|
||||||
this.languageInfoButton.popover({});
|
BootstrapUtils.initPopover(this.languageInfoButton);
|
||||||
this.languageBtn = this.domRoot.find('.change-language');
|
this.languageBtn = this.domRoot.find('.change-language');
|
||||||
const changeLanguageButton = this.languageBtn[0];
|
const changeLanguageButton = this.languageBtn[0];
|
||||||
assert(changeLanguageButton instanceof HTMLSelectElement);
|
assert(changeLanguageButton instanceof HTMLSelectElement);
|
||||||
@@ -598,7 +599,10 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
.createDragSource(dragSource, dragConfig)
|
.createDragSource(dragSource, dragConfig)
|
||||||
// @ts-expect-error: createDragSource returns not void
|
// @ts-expect-error: createDragSource returns not void
|
||||||
._dragListener.on('dragStart', () => {
|
._dragListener.on('dragStart', () => {
|
||||||
paneAdderDropdown.dropdown('toggle');
|
const dropdown = BootstrapUtils.getDropdownInstance(paneAdderDropdown);
|
||||||
|
if (dropdown) {
|
||||||
|
dropdown.toggle();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
dragSource.on('click', () => {
|
dragSource.on('click', () => {
|
||||||
@@ -1921,7 +1925,7 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
): string {
|
): string {
|
||||||
let result =
|
let result =
|
||||||
'<div class="d-flex" style="align-items: center">' +
|
'<div class="d-flex" style="align-items: center">' +
|
||||||
'<div class="mr-1 d-flex" style="align-items: center">' +
|
'<div class="me-1 d-flex" style="align-items: center">' +
|
||||||
'<img src="' +
|
'<img src="' +
|
||||||
(data.logoData ? data.logoData : '') +
|
(data.logoData ? data.logoData : '') +
|
||||||
'" class="' +
|
'" class="' +
|
||||||
@@ -1961,9 +1965,12 @@ export class Editor extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Edit
|
|||||||
onCompiler(compilerId: number, compiler: unknown, options: string, editorId: number, treeId: number): void {}
|
onCompiler(compilerId: number, compiler: unknown, options: string, editorId: number, treeId: number): void {}
|
||||||
|
|
||||||
updateLanguageTooltip() {
|
updateLanguageTooltip() {
|
||||||
this.languageInfoButton.popover('dispose');
|
// Dispose existing popover instance
|
||||||
|
const existingPopover = BootstrapUtils.getPopoverInstance(this.languageInfoButton);
|
||||||
|
if (existingPopover) existingPopover.dispose();
|
||||||
|
|
||||||
if (this.currentLanguage?.tooltip) {
|
if (this.currentLanguage?.tooltip) {
|
||||||
this.languageInfoButton.popover({
|
BootstrapUtils.initPopover(this.languageInfoButton, {
|
||||||
title: 'More info about this language',
|
title: 'More info about this language',
|
||||||
content: this.currentLanguage.tooltip,
|
content: this.currentLanguage.tooltip,
|
||||||
container: 'body',
|
container: 'body',
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {Language} from '../../types/languages.interfaces.js';
|
|||||||
import {ResultLine} from '../../types/resultline/resultline.interfaces.js';
|
import {ResultLine} from '../../types/resultline/resultline.interfaces.js';
|
||||||
import {Artifact, ArtifactType} from '../../types/tool.interfaces.js';
|
import {Artifact, ArtifactType} from '../../types/tool.interfaces.js';
|
||||||
import {Filter as AnsiToHtml} from '../ansi-to-html.js';
|
import {Filter as AnsiToHtml} from '../ansi-to-html.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {CompilationStatus as CompilerServiceCompilationStatus} from '../compiler-service.interfaces.js';
|
import {CompilationStatus as CompilerServiceCompilationStatus} from '../compiler-service.interfaces.js';
|
||||||
import {CompilerService} from '../compiler-service.js';
|
import {CompilerService} from '../compiler-service.js';
|
||||||
import {ICompilerShared} from '../compiler-shared.interfaces.js';
|
import {ICompilerShared} from '../compiler-shared.interfaces.js';
|
||||||
@@ -799,15 +800,19 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
!target.is(this.prependOptions) &&
|
!target.is(this.prependOptions) &&
|
||||||
this.prependOptions.has(target as any).length === 0 &&
|
this.prependOptions.has(target as any).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
)
|
) {
|
||||||
this.prependOptions.popover('hide');
|
const popover = BootstrapUtils.getPopoverInstance(this.prependOptions);
|
||||||
|
if (popover) popover.hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!target.is(this.fullCompilerName) &&
|
!target.is(this.fullCompilerName) &&
|
||||||
this.fullCompilerName.has(target as any).length === 0 &&
|
this.fullCompilerName.has(target as any).length === 0 &&
|
||||||
target.closest('.popover').length === 0
|
target.closest('.popover').length === 0
|
||||||
)
|
) {
|
||||||
this.fullCompilerName.popover('hide');
|
const popover = BootstrapUtils.getPopoverInstance(this.fullCompilerName);
|
||||||
|
if (popover) popover.hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.optionsField.val(this.options);
|
this.optionsField.val(this.options);
|
||||||
@@ -963,7 +968,8 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
// Dismiss the popover on escape.
|
// Dismiss the popover on escape.
|
||||||
$(document).on('keyup.editable', e => {
|
$(document).on('keyup.editable', e => {
|
||||||
if (e.which === 27) {
|
if (e.which === 27) {
|
||||||
this.libsButton.popover('hide');
|
const popover = BootstrapUtils.getPopoverInstance(this.libsButton);
|
||||||
|
if (popover) popover.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -997,7 +1003,8 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
const elem = this.libsButton;
|
const elem = this.libsButton;
|
||||||
const target = $(e.target);
|
const target = $(e.target);
|
||||||
if (!target.is(elem) && elem.has(target as any).length === 0 && target.closest('.popover').length === 0) {
|
if (!target.is(elem) && elem.has(target as any).length === 0 && target.closest('.popover').length === 0) {
|
||||||
elem.popover('hide');
|
const popover = BootstrapUtils.getPopoverInstance(elem);
|
||||||
|
if (popover) popover.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1186,8 +1193,12 @@ export class Executor extends Pane<ExecutorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCompilationOptionsPopover(content: string | null) {
|
setCompilationOptionsPopover(content: string | null) {
|
||||||
this.prependOptions.popover('dispose');
|
// Dispose of existing popover
|
||||||
this.prependOptions.popover({
|
const existingPopover = BootstrapUtils.getPopoverInstance(this.prependOptions);
|
||||||
|
if (existingPopover) existingPopover.dispose();
|
||||||
|
|
||||||
|
// Initialize new popover
|
||||||
|
BootstrapUtils.initPopover(this.prependOptions, {
|
||||||
content: content || 'No options in use',
|
content: content || 'No options in use',
|
||||||
template:
|
template:
|
||||||
'<div class="popover' +
|
'<div class="popover' +
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import TomSelect from 'tom-select';
|
|||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
import {escapeHTML} from '../../shared/common-utils.js';
|
import {escapeHTML} from '../../shared/common-utils.js';
|
||||||
import {assert, unwrap, unwrapString} from '../assert.js';
|
import {assert, unwrap, unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import * as Components from '../components.js';
|
import * as Components from '../components.js';
|
||||||
import {EventHub} from '../event-hub.js';
|
import {EventHub} from '../event-hub.js';
|
||||||
import {Hub} from '../hub.js';
|
import {Hub} from '../hub.js';
|
||||||
@@ -448,7 +449,11 @@ export class Tree {
|
|||||||
(this.container.layoutManager.createDragSource(dragSource, dragConfig.bind(this)) as any)._dragListener.on(
|
(this.container.layoutManager.createDragSource(dragSource, dragConfig.bind(this)) as any)._dragListener.on(
|
||||||
'dragStart',
|
'dragStart',
|
||||||
() => {
|
() => {
|
||||||
this.domRoot.find('.add-pane').dropdown('toggle');
|
const dropdown = this.domRoot.find('.add-pane');
|
||||||
|
const dropdownInstance = BootstrapUtils.getDropdownInstance(dropdown);
|
||||||
|
if (dropdownInstance) {
|
||||||
|
dropdownInstance.toggle();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export function setupRealDark(hub: Hub) {
|
|||||||
$('#settings .theme').val('real-dark').trigger('change');
|
$('#settings .theme').val('real-dark').trigger('change');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#true-dark .content .close').on('click', e => {
|
$('#true-dark .content .dark-close').on('click', e => {
|
||||||
local.localStorage.set(localKey, 'hidden');
|
local.localStorage.set(localKey, 'hidden');
|
||||||
toggleButton();
|
toggleButton();
|
||||||
toggleOverlay();
|
toggleOverlay();
|
||||||
|
|||||||
@@ -22,18 +22,20 @@
|
|||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import {Modal, Tooltip} from 'bootstrap';
|
||||||
import ClipboardJS from 'clipboard';
|
import ClipboardJS from 'clipboard';
|
||||||
import GoldenLayout from 'golden-layout';
|
import GoldenLayout from 'golden-layout';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
|
import {unwrap} from './assert.js';
|
||||||
|
import * as BootstrapUtils from './bootstrap-utils.js';
|
||||||
import {sessionThenLocalStorage} from './local.js';
|
import {sessionThenLocalStorage} from './local.js';
|
||||||
import {options} from './options.js';
|
import {options} from './options.js';
|
||||||
import * as url from './url.js';
|
import * as url from './url.js';
|
||||||
|
|
||||||
import ClickEvent = JQuery.ClickEvent;
|
|
||||||
import TriggeredEvent = JQuery.TriggeredEvent;
|
|
||||||
import {SentryCapture} from './sentry.js';
|
import {SentryCapture} from './sentry.js';
|
||||||
import {Settings, SiteSettings} from './settings.js';
|
import {Settings, SiteSettings} from './settings.js';
|
||||||
|
import ClickEvent = JQuery.ClickEvent;
|
||||||
|
|
||||||
const cloneDeep = require('lodash.clonedeep');
|
const cloneDeep = require('lodash.clonedeep');
|
||||||
|
|
||||||
@@ -87,24 +89,31 @@ export class Sharing {
|
|||||||
private layout: GoldenLayout;
|
private layout: GoldenLayout;
|
||||||
private lastState: any;
|
private lastState: any;
|
||||||
|
|
||||||
private share: JQuery;
|
private readonly share: JQuery;
|
||||||
private shareShort: JQuery;
|
private readonly shareTooltipTarget: JQuery;
|
||||||
private shareFull: JQuery;
|
private readonly shareShort: JQuery;
|
||||||
private shareEmbed: JQuery;
|
private readonly shareFull: JQuery;
|
||||||
|
private readonly shareEmbed: JQuery;
|
||||||
|
|
||||||
private settings: SiteSettings;
|
private settings: SiteSettings;
|
||||||
|
|
||||||
private clippyButton: ClipboardJS | null;
|
private clippyButton: ClipboardJS | null;
|
||||||
|
private readonly shareLinkDialog: HTMLElement;
|
||||||
|
|
||||||
constructor(layout: any) {
|
constructor(layout: any) {
|
||||||
this.layout = layout;
|
this.layout = layout;
|
||||||
this.lastState = null;
|
this.lastState = null;
|
||||||
|
this.shareLinkDialog = unwrap(document.getElementById('sharelinkdialog'), 'Share modal element not found');
|
||||||
|
|
||||||
this.share = $('#share');
|
this.share = $('#share');
|
||||||
|
this.shareTooltipTarget = $('#share-tooltip-target');
|
||||||
this.shareShort = $('#shareShort');
|
this.shareShort = $('#shareShort');
|
||||||
this.shareFull = $('#shareFull');
|
this.shareFull = $('#shareFull');
|
||||||
this.shareEmbed = $('#shareEmbed');
|
this.shareEmbed = $('#shareEmbed');
|
||||||
|
|
||||||
|
[this.shareShort, this.shareFull, this.shareEmbed].forEach(el =>
|
||||||
|
el.on('click', e => BootstrapUtils.showModal(this.shareLinkDialog, e.currentTarget)),
|
||||||
|
);
|
||||||
this.settings = Settings.getStoredSettings();
|
this.settings = Settings.getStoredSettings();
|
||||||
|
|
||||||
this.clippyButton = null;
|
this.clippyButton = null;
|
||||||
@@ -122,9 +131,9 @@ export class Sharing {
|
|||||||
});
|
});
|
||||||
this.layout.on('stateChanged', this.onStateChanged.bind(this));
|
this.layout.on('stateChanged', this.onStateChanged.bind(this));
|
||||||
|
|
||||||
$('#sharelinkdialog')
|
BootstrapUtils.initModal(this.shareLinkDialog);
|
||||||
.on('show.bs.modal', this.onOpenModalPane.bind(this))
|
this.shareLinkDialog.addEventListener('show.bs.modal', this.onOpenModalPane.bind(this));
|
||||||
.on('hidden.bs.modal', this.onCloseModalPane.bind(this));
|
this.shareLinkDialog.addEventListener('hidden.bs.modal', this.onCloseModalPane.bind(this));
|
||||||
|
|
||||||
this.layout.eventHub.on('settingsChange', (newSettings: SiteSettings) => {
|
this.layout.eventHub.on('settingsChange', (newSettings: SiteSettings) => {
|
||||||
this.settings = newSettings;
|
this.settings = newSettings;
|
||||||
@@ -176,11 +185,16 @@ export class Sharing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onOpenModalPane(event: TriggeredEvent<HTMLElement, undefined, HTMLElement, HTMLElement>): void {
|
private onOpenModalPane(event: Event): void {
|
||||||
// @ts-ignore The property is added by bootstrap
|
const modalEvent = event as Modal.Event;
|
||||||
const button = $(event.relatedTarget);
|
if (!modalEvent.relatedTarget) {
|
||||||
const currentBind = Sharing.bindToLinkType(button.data('bind'));
|
throw new Error('No relatedTarget found in modal event');
|
||||||
const modal = $(event.currentTarget);
|
}
|
||||||
|
|
||||||
|
const button = $(modalEvent.relatedTarget);
|
||||||
|
const bindStr = button.data('bind') as string;
|
||||||
|
const currentBind = Sharing.bindToLinkType(bindStr);
|
||||||
|
const modal = $(event.currentTarget as HTMLElement);
|
||||||
const socialSharingElements = modal.find('.socialsharing');
|
const socialSharingElements = modal.find('.socialsharing');
|
||||||
const permalink = modal.find('.permalink');
|
const permalink = modal.find('.permalink');
|
||||||
const embedsettings = modal.find('#embedsettings');
|
const embedsettings = modal.find('#embedsettings');
|
||||||
@@ -262,15 +276,16 @@ export class Sharing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onClipButtonPressed(event: ClickEvent, type: LinkType): void {
|
private onClipButtonPressed(event: ClickEvent, type: LinkType): boolean {
|
||||||
// Don't let the modal show up.
|
// Don't let the modal show up.
|
||||||
// We need this because the button is a child of the dropdown-item with a data-toggle=modal
|
// We need this because the button is a child of the dropdown-item with a data-bs-toggle=modal
|
||||||
if (Sharing.isNavigatorClipboardAvailable()) {
|
if (Sharing.isNavigatorClipboardAvailable()) {
|
||||||
event.stopPropagation();
|
|
||||||
this.copyLinkTypeToClipboard(type);
|
this.copyLinkTypeToClipboard(type);
|
||||||
// As we prevented bubbling, the dropdown won't close by itself. We need to trigger it manually
|
event.stopPropagation();
|
||||||
this.share.dropdown('hide');
|
// As we prevented bubbling, the dropdown won't close by itself.
|
||||||
|
BootstrapUtils.hideDropdown(this.share);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLinkOfType(type: LinkType): Promise<string> {
|
private getLinkOfType(type: LinkType): Promise<string> {
|
||||||
@@ -278,7 +293,7 @@ export class Sharing {
|
|||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
Sharing.getLinks(config, type, (error: any, newUrl: string, extra: string, updateState: boolean) => {
|
Sharing.getLinks(config, type, (error: any, newUrl: string, extra: string, updateState: boolean) => {
|
||||||
if (error || !newUrl) {
|
if (error || !newUrl) {
|
||||||
this.displayTooltip(this.share, 'Oops, something went wrong');
|
this.displayTooltip(this.shareTooltipTarget, 'Oops, something went wrong');
|
||||||
SentryCapture(error, 'Getting short link failed');
|
SentryCapture(error, 'Getting short link failed');
|
||||||
reject();
|
reject();
|
||||||
} else {
|
} else {
|
||||||
@@ -295,7 +310,7 @@ export class Sharing {
|
|||||||
const config = this.layout.toConfig();
|
const config = this.layout.toConfig();
|
||||||
Sharing.getLinks(config, type, (error: any, newUrl: string, extra: string, updateState: boolean) => {
|
Sharing.getLinks(config, type, (error: any, newUrl: string, extra: string, updateState: boolean) => {
|
||||||
if (error || !newUrl) {
|
if (error || !newUrl) {
|
||||||
this.displayTooltip(this.share, 'Oops, something went wrong');
|
this.displayTooltip(this.shareTooltipTarget, 'Oops, something went wrong');
|
||||||
SentryCapture(error, 'Getting short link failed');
|
SentryCapture(error, 'Getting short link failed');
|
||||||
} else {
|
} else {
|
||||||
if (updateState) {
|
if (updateState) {
|
||||||
@@ -306,16 +321,33 @@ export class Sharing {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO we can consider using bootstrap's "Toast" support in future.
|
||||||
private displayTooltip(where: JQuery, message: string): void {
|
private displayTooltip(where: JQuery, message: string): void {
|
||||||
where.tooltip('dispose');
|
// First dispose any existing tooltip
|
||||||
where.tooltip({
|
const tooltipEl = where[0];
|
||||||
|
if (!tooltipEl) return;
|
||||||
|
|
||||||
|
const existingTooltip = Tooltip.getInstance(tooltipEl);
|
||||||
|
if (existingTooltip) {
|
||||||
|
existingTooltip.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and show new tooltip
|
||||||
|
try {
|
||||||
|
const tooltip = BootstrapUtils.initTooltip(tooltipEl, {
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
trigger: 'manual',
|
trigger: 'manual',
|
||||||
title: message,
|
title: message,
|
||||||
});
|
});
|
||||||
where.tooltip('show');
|
|
||||||
|
tooltip.show();
|
||||||
|
|
||||||
// Manual triggering of tooltips does not hide them automatically. This timeout ensures they do
|
// Manual triggering of tooltips does not hide them automatically. This timeout ensures they do
|
||||||
setTimeout(() => where.tooltip('hide'), 1500);
|
setTimeout(() => tooltip.hide(), 1500);
|
||||||
|
} catch (e) {
|
||||||
|
// If element doesn't exist, just silently fail
|
||||||
|
console.warn('Could not show tooltip:', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private openShareModalForType(type: LinkType): void {
|
private openShareModalForType(type: LinkType): void {
|
||||||
@@ -336,7 +368,7 @@ export class Sharing {
|
|||||||
if (Sharing.isNavigatorClipboardAvailable()) {
|
if (Sharing.isNavigatorClipboardAvailable()) {
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.writeText(link)
|
.writeText(link)
|
||||||
.then(() => this.displayTooltip(this.share, 'Link copied to clipboard'))
|
.then(() => this.displayTooltip(this.shareTooltipTarget, 'Link copied to clipboard'))
|
||||||
.catch(() => this.openShareModalForType(type));
|
.catch(() => this.openShareModalForType(type));
|
||||||
} else {
|
} else {
|
||||||
this.openShareModalForType(type);
|
this.openShareModalForType(type);
|
||||||
@@ -397,7 +429,7 @@ export class Sharing {
|
|||||||
): string {
|
): string {
|
||||||
const embedUrl = Sharing.getEmbeddedUrl(config, root, isReadOnly, extraOptions);
|
const embedUrl = Sharing.getEmbeddedUrl(config, root, isReadOnly, extraOptions);
|
||||||
// The attributes must be double quoted, the full url's rison contains single quotes
|
// The attributes must be double quoted, the full url's rison contains single quotes
|
||||||
return `<iframe width="800px" height="200px" src="${embedUrl}"></iframe>`;
|
return `<iframe width='800px' height='200px' src='${embedUrl}'></iframe>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getEmbeddedUrl(config: any, root: string, readOnly: boolean, extraOptions: object): string {
|
private static getEmbeddedUrl(config: any, root: string, readOnly: boolean, extraOptions: object): string {
|
||||||
@@ -455,7 +487,7 @@ export class Sharing {
|
|||||||
const newElement = baseTemplate.children('a.share-item').clone();
|
const newElement = baseTemplate.children('a.share-item').clone();
|
||||||
if (service.logoClass) {
|
if (service.logoClass) {
|
||||||
newElement.prepend(
|
newElement.prepend(
|
||||||
$('<span>').addClass('dropdown-icon mr-1').addClass(service.logoClass).prop('title', serviceName),
|
$('<span>').addClass('dropdown-icon me-1').addClass(service.logoClass).prop('title', serviceName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (service.text) {
|
if (service.text) {
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix for Bootstrap 5 navbar
|
||||||
|
.navbar .container-fluid {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-brand img.logo-overlay {
|
.navbar-brand img.logo-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -75,13 +80,23 @@ body {
|
|||||||
|
|
||||||
.compiler-picker {
|
.compiler-picker {
|
||||||
min-width: 14em;
|
min-width: 14em;
|
||||||
|
flex-grow: 0.2 !important; // Ensures the compiler picker doesn't flex-grow too much and take up more space
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent TomSelect items from spilling onto multiple lines
|
||||||
|
.ts-wrapper .item {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compiler-picker .ts-input {
|
.compiler-picker .ts-input {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-left: none !important;
|
border-left: none !important; /* Fallback for older browsers */
|
||||||
border-top-left-radius: 0;
|
border-inline-start: none !important; /* Logical property for RTL support */
|
||||||
border-bottom-left-radius: 0;
|
border-top-left-radius: 0; /* Fallback for older browsers */
|
||||||
|
border-bottom-left-radius: 0; /* Fallback for older browsers */
|
||||||
|
border-start-start-radius: 0; /* Logical property for RTL support */
|
||||||
|
border-end-start-radius: 0; /* Logical property for RTL support */
|
||||||
}
|
}
|
||||||
|
|
||||||
.function-picker {
|
.function-picker {
|
||||||
@@ -294,6 +309,12 @@ pre.content.wrap * {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#site-template-loader {
|
||||||
|
.modal-dialog {
|
||||||
|
min-width: 800px; /* ensure template modal has adequate width */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.modal-body {
|
.modal-body {
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
overflow-y: auto; /* make body scrollable -> keep Header & Footer onscreen, if possible */
|
overflow-y: auto; /* make body scrollable -> keep Header & Footer onscreen, if possible */
|
||||||
@@ -377,7 +398,7 @@ pre.content.wrap * {
|
|||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast-header .close {
|
.toast-header .btn-close {
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
@@ -387,17 +408,25 @@ pre.content.wrap * {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.font-size-list {
|
.font-size-list {
|
||||||
min-width: 43px !important;
|
min-width: 60px !important;
|
||||||
max-height: 70% !important;
|
max-height: 70vh !important;
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
width: auto;
|
width: auto;
|
||||||
// For my fellow Firefox users
|
// For my fellow Firefox users
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
padding: 0.25rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-size-list button {
|
.font-size-list button {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-size-list button:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.075);
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-option {
|
.font-option {
|
||||||
@@ -893,18 +922,19 @@ div.populararguments div.dropdown-menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.corporate .ces {
|
.corporate .ces {
|
||||||
font-size: 165%;
|
.btn {
|
||||||
height: 9em;
|
--bs-btn-font-size: 24px;
|
||||||
|
}
|
||||||
|
height: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legendary .ces {
|
.legendary .ces {
|
||||||
font-size: 165%;
|
.btn {
|
||||||
height: 7em;
|
--bs-btn-font-size: 24px;
|
||||||
}
|
|
||||||
|
|
||||||
.legendary .ces button {
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
height: 20em;
|
||||||
|
}
|
||||||
|
|
||||||
.ces-logo {
|
.ces-logo {
|
||||||
max-height: 1.5em;
|
max-height: 1.5em;
|
||||||
@@ -1115,7 +1145,7 @@ div.populararguments div.dropdown-menu {
|
|||||||
margin-right: 2pt;
|
margin-right: 2pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.badge.badge-pill {
|
span.badge.rounded-pill {
|
||||||
margin-left: 2pt;
|
margin-left: 2pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,11 +1215,42 @@ html[data-theme='one-dark'] {
|
|||||||
padding-right: 2rem !important;
|
padding-right: 2rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add back the dropdown arrow for TomSelect in Bootstrap 5 */
|
||||||
|
.ts-wrapper.single .ts-control:not(.input-active)::after {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 15px;
|
||||||
|
margin-top: -3px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 5px 0 5px;
|
||||||
|
border-color: #343a40 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for the dropdown arrow when dropdown is active */
|
||||||
|
.ts-wrapper.single.dropdown-active .ts-control::after {
|
||||||
|
margin-top: -4px;
|
||||||
|
border-width: 0 5px 5px 5px;
|
||||||
|
border-color: transparent transparent #343a40 transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix Bootstrap 5's input-group border overlap issues with TomSelect
|
||||||
|
// Bootstrap applies a -1px margin to elements matching `:not(:first-child)` in input groups
|
||||||
|
// TomSelect creates a wrapper (.ts-wrapper) around the select element, which becomes a
|
||||||
|
// child of the input-group. This wrapper gets the negative margin, causing it to shift
|
||||||
|
// left by 1px and visually overflow its container boundary.
|
||||||
|
.input-group > .ts-wrapper:not(:first-child) {
|
||||||
|
margin-left: 0 !important; // Reset Bootstrap's negative margin for TomSelect wrappers
|
||||||
|
}
|
||||||
|
|
||||||
.copy-link-btn {
|
.copy-link-btn {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conformance-wrapper .compiler-list .form-row {
|
.conformance-wrapper .compiler-list .row {
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1229,8 +1290,10 @@ html[data-theme='one-dark'] {
|
|||||||
|
|
||||||
.prepend-options,
|
.prepend-options,
|
||||||
.picker-popout-button {
|
.picker-popout-button {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0; /* Fallback for older browsers */
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0; /* Fallback for older browsers */
|
||||||
|
border-start-end-radius: 0; /* Logical property for RTL support */
|
||||||
|
border-end-end-radius: 0; /* Logical property for RTL support */
|
||||||
}
|
}
|
||||||
|
|
||||||
.picker-popout-button {
|
.picker-popout-button {
|
||||||
@@ -1257,7 +1320,9 @@ html[data-theme='one-dark'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.popular-arguments-btn {
|
.popular-arguments-btn {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0; /* Fallback for older browsers */
|
||||||
|
border-start-end-radius: 0; /* Logical property for RTL support */
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-compilation {
|
.panel-compilation {
|
||||||
@@ -1315,9 +1380,14 @@ html[data-theme='one-dark'] {
|
|||||||
> div {
|
> div {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
&.site-templates-list-col {
|
||||||
|
min-width: 150px;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
&.site-template-preview-col {
|
&.site-template-preview-col {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
min-width: 400px;
|
||||||
img {
|
img {
|
||||||
width: 1000px;
|
width: 1000px;
|
||||||
aspect-ratio: 1000 / 800;
|
aspect-ratio: 1000 / 800;
|
||||||
@@ -1579,11 +1649,11 @@ html[data-theme='one-dark'] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.close {
|
.dark-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0;
|
||||||
right: -12px;
|
right: -12px;
|
||||||
//background: #e787e7;
|
padding: 0;
|
||||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #1a1a1a 48%, #1a1a1a 100%);
|
background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #1a1a1a 48%, #1a1a1a 100%);
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|||||||
@@ -28,12 +28,24 @@ body {
|
|||||||
background-color: #333 !important;
|
background-color: #333 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Border color adjustments for form elements in dark theme
|
||||||
|
.form-select,
|
||||||
|
.form-control,
|
||||||
|
.input-group-text,
|
||||||
|
.ts-wrapper .ts-control {
|
||||||
|
--bs-border-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
textarea {
|
textarea {
|
||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: #474747;
|
background-color: #474747;
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #888 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: #474747;
|
background-color: #474747;
|
||||||
@@ -166,7 +178,7 @@ textarea.form-control {
|
|||||||
.conformance-wrapper {
|
.conformance-wrapper {
|
||||||
background-color: #1e1e1e !important;
|
background-color: #1e1e1e !important;
|
||||||
|
|
||||||
.compiler-list .form-row {
|
.compiler-list .row {
|
||||||
border-bottom: 1px solid #3e3e3e;
|
border-bottom: 1px solid #3e3e3e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +196,7 @@ textarea.form-control {
|
|||||||
background-color: rgba(49, 54, 60, 0.85);
|
background-color: rgba(49, 54, 60, 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select {
|
.form-select {
|
||||||
background-color: #76a1c8 !important;
|
background-color: #76a1c8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +208,11 @@ textarea.form-control {
|
|||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
background-color: #23272b !important;
|
background-color: #23272b !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #235765 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
@@ -366,8 +383,8 @@ textarea.form-control {
|
|||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: #333 !important;
|
background-color: #333 !important;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,8 +454,8 @@ textarea.form-control {
|
|||||||
background-color: #aa3333 !important;
|
background-color: #aa3333 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,8 +468,8 @@ textarea.form-control {
|
|||||||
background-color: #222 !important;
|
background-color: #222 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,16 +164,16 @@ a.navbar-brand img.logo.normal {
|
|||||||
.notification-error {
|
.notification-error {
|
||||||
background-color: indianred;
|
background-color: indianred;
|
||||||
color: white;
|
color: white;
|
||||||
.close {
|
.btn-close {
|
||||||
color: white;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification-on {
|
.notification-on {
|
||||||
background-color: green;
|
background-color: green;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
.close {
|
.btn-close {
|
||||||
color: white;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ div.argmenuitem span.argdescription {
|
|||||||
color: #007bfd;
|
color: #007bfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conformance-wrapper .compiler-list .form-row {
|
.conformance-wrapper .compiler-list .row {
|
||||||
border-bottom: 1px solid #e3e3e3;
|
border-bottom: 1px solid #e3e3e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +387,11 @@ div.argmenuitem span.argdescription {
|
|||||||
background-color: #dae0e5;
|
background-color: #dae0e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-item.active {
|
||||||
|
background-color: #007bfd;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.currentCursorPosition {
|
.currentCursorPosition {
|
||||||
color: #15a3b9;
|
color: #15a3b9;
|
||||||
background-color: darken(rgba(248, 249, 250, 0.85), 3%);
|
background-color: darken(rgba(248, 249, 250, 0.85), 3%);
|
||||||
|
|||||||
@@ -39,11 +39,23 @@ body {
|
|||||||
background-color: $base !important;
|
background-color: $base !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Border color adjustments for form elements in dark theme
|
||||||
|
.form-select,
|
||||||
|
.form-control,
|
||||||
|
.input-group-text,
|
||||||
|
.ts-wrapper .ts-control {
|
||||||
|
--bs-border-color: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: $lighter;
|
background-color: $lighter;
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #888 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: $lightest;
|
background-color: $lightest;
|
||||||
@@ -204,7 +216,7 @@ textarea.form-control {
|
|||||||
.conformance-wrapper {
|
.conformance-wrapper {
|
||||||
background-color: #1e1e1e !important;
|
background-color: #1e1e1e !important;
|
||||||
|
|
||||||
.compiler-list .form-row {
|
.compiler-list .row {
|
||||||
border-bottom: 1px solid #3e3e3e;
|
border-bottom: 1px solid #3e3e3e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +234,7 @@ textarea.form-control {
|
|||||||
background-color: opacify($dark, 0.8);
|
background-color: opacify($dark, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select {
|
.form-select {
|
||||||
background-color: #dddddd !important;
|
background-color: #dddddd !important;
|
||||||
color: #000 !important;
|
color: #000 !important;
|
||||||
}
|
}
|
||||||
@@ -235,6 +247,11 @@ textarea.form-control {
|
|||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
background-color: $lighter !important;
|
background-color: $lighter !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #405f9d !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
@@ -325,7 +342,7 @@ textarea.form-control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#v-status {
|
.v-status {
|
||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,8 +439,8 @@ textarea.form-control {
|
|||||||
color: #eee !important;
|
color: #eee !important;
|
||||||
background-color: $base !important;
|
background-color: $base !important;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #eee;
|
filter: invert(90%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,8 +510,8 @@ textarea.form-control {
|
|||||||
background-color: #aa3333 !important;
|
background-color: #aa3333 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,8 +524,8 @@ textarea.form-control {
|
|||||||
background-color: #222 !important;
|
background-color: #222 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ body {
|
|||||||
background-color: $base !important;
|
background-color: $base !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Border color adjustments for form elements
|
||||||
|
.form-select,
|
||||||
|
.form-control,
|
||||||
|
.input-group-text,
|
||||||
|
.ts-wrapper .ts-control {
|
||||||
|
--bs-border-color: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
//color: #000 !important;
|
//color: #000 !important;
|
||||||
background-color: $base;
|
background-color: $base;
|
||||||
@@ -174,7 +182,7 @@ textarea.form-control {
|
|||||||
.conformance-wrapper {
|
.conformance-wrapper {
|
||||||
background-color: #1e1e1e !important;
|
background-color: #1e1e1e !important;
|
||||||
|
|
||||||
.compiler-list .form-row {
|
.compiler-list .row {
|
||||||
border-bottom: 1px solid #3e3e3e;
|
border-bottom: 1px solid #3e3e3e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +196,7 @@ textarea.form-control {
|
|||||||
background-color: opacify($dark, 0.8);
|
background-color: opacify($dark, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-select {
|
.form-select {
|
||||||
background-color: #76a1c8 !important;
|
background-color: #76a1c8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +206,11 @@ textarea.form-control {
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: $dark !important;
|
background-color: $dark !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: $darker !important;
|
||||||
|
color: #212529 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
@@ -383,10 +396,6 @@ textarea.form-control {
|
|||||||
color: #212529 !important;
|
color: #212529 !important;
|
||||||
background-color: $base !important;
|
background-color: $base !important;
|
||||||
border-bottom-color: $dark;
|
border-bottom-color: $dark;
|
||||||
|
|
||||||
.close {
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav.nav-tabs {
|
.nav.nav-tabs {
|
||||||
@@ -459,8 +468,8 @@ textarea.form-control {
|
|||||||
background-color: #aa3333 !important;
|
background-color: #aa3333 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,8 +482,8 @@ textarea.form-control {
|
|||||||
background-color: #222 !important;
|
background-color: #222 !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
.close {
|
.btn-close {
|
||||||
color: #fff;
|
filter: invert(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {AlertAskOptions, AlertEnterTextOptions, AlertNotifyOptions} from './alert.interfaces.js';
|
import {AlertAskOptions, AlertEnterTextOptions, AlertNotifyOptions} from './alert.interfaces.js';
|
||||||
|
|
||||||
export class Alert {
|
export class Alert {
|
||||||
@@ -57,10 +58,10 @@ export class Alert {
|
|||||||
modal.toggleClass('error-alert', isError === true);
|
modal.toggleClass('error-alert', isError === true);
|
||||||
modal.find('.modal-title').html(title);
|
modal.find('.modal-title').html(title);
|
||||||
modal.find('.modal-body').html(body);
|
modal.find('.modal-body').html(body);
|
||||||
modal.modal();
|
BootstrapUtils.showModal(modal);
|
||||||
|
|
||||||
if (onClose) {
|
if (onClose) {
|
||||||
modal.off('hidden.bs.modal');
|
BootstrapUtils.setElementEventHandler(modal, 'hidden.bs.modal', onClose);
|
||||||
modal.on('hidden.bs.modal', onClose);
|
|
||||||
}
|
}
|
||||||
return modal;
|
return modal;
|
||||||
}
|
}
|
||||||
@@ -83,10 +84,10 @@ export class Alert {
|
|||||||
modal.find('.modal-footer .no').removeClass('btn-link').addClass(askOptions.noClass);
|
modal.find('.modal-footer .no').removeClass('btn-link').addClass(askOptions.noClass);
|
||||||
}
|
}
|
||||||
if (askOptions.onClose) {
|
if (askOptions.onClose) {
|
||||||
modal.off('hidden.bs.modal');
|
BootstrapUtils.setElementEventHandler(modal, 'hidden.bs.modal', askOptions.onClose);
|
||||||
modal.on('hidden.bs.modal', askOptions.onClose);
|
|
||||||
}
|
}
|
||||||
modal.modal();
|
|
||||||
|
BootstrapUtils.showModal(modal);
|
||||||
return modal;
|
return modal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +109,8 @@ export class Alert {
|
|||||||
const newElement = $(`
|
const newElement = $(`
|
||||||
<div class="toast" tabindex="-1" role="alert" aria-live="assertive" aria-atomic="true">
|
<div class="toast" tabindex="-1" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
<div class="toast-header ${alertClass}">
|
<div class="toast-header ${alertClass}">
|
||||||
<strong class="mr-auto">${this.prefixMessage}</strong>
|
<strong class="me-auto">${this.prefixMessage}</strong>
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
<button type="button" class="ms-2 mb-1 btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="toast-body ${alertClass}">
|
<div class="toast-body ${alertClass}">
|
||||||
<span id="msg">${body}</span>
|
<span id="msg">${body}</span>
|
||||||
@@ -119,21 +118,26 @@ export class Alert {
|
|||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
container.append(newElement);
|
container.append(newElement);
|
||||||
newElement.toast({
|
const toastOptions = {
|
||||||
autohide: autoDismiss,
|
autohide: autoDismiss,
|
||||||
delay: dismissTime,
|
delay: dismissTime,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
BootstrapUtils.initToast(newElement, toastOptions);
|
||||||
|
|
||||||
if (group !== '') {
|
if (group !== '') {
|
||||||
if (collapseSimilar) {
|
if (collapseSimilar) {
|
||||||
// Only collapsing if a group has been specified
|
// Only collapsing if a group has been specified
|
||||||
const old = container.find(`[data-group="${group}"]`);
|
const old = container.find(`[data-group="${group}"]`);
|
||||||
old.toast('hide');
|
old.each((_, element) => {
|
||||||
old.remove();
|
BootstrapUtils.hideToast(element);
|
||||||
|
$(element).remove();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
newElement.attr('data-group', group);
|
newElement.attr('data-group', group);
|
||||||
}
|
}
|
||||||
onBeforeShow(newElement);
|
onBeforeShow(newElement);
|
||||||
newElement.toast('show');
|
BootstrapUtils.showToast(newElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,14 +178,13 @@ export class Alert {
|
|||||||
noButton.removeClass('btn-light').addClass(askOptions.noClass);
|
noButton.removeClass('btn-light').addClass(askOptions.noClass);
|
||||||
}
|
}
|
||||||
if (askOptions.onClose) {
|
if (askOptions.onClose) {
|
||||||
modal.off('hidden.bs.modal');
|
BootstrapUtils.setElementEventHandler(modal, 'hidden.bs.modal', askOptions.onClose);
|
||||||
modal.on('hidden.bs.modal', askOptions.onClose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modal.on('shown.bs.modal', () => {
|
BootstrapUtils.setElementEventHandler(modal, 'shown.bs.modal', () => {
|
||||||
answerEdit.trigger('focus');
|
answerEdit.trigger('focus');
|
||||||
});
|
});
|
||||||
modal.modal();
|
BootstrapUtils.showModal(modal);
|
||||||
return modal;
|
return modal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
EnvVarOverrides,
|
EnvVarOverrides,
|
||||||
} from '../../types/compilation/compiler-overrides.interfaces.js';
|
} from '../../types/compilation/compiler-overrides.interfaces.js';
|
||||||
import {assert, unwrap} from '../assert.js';
|
import {assert, unwrap} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {CompilerInfo} from '../compiler.interfaces.js';
|
import {CompilerInfo} from '../compiler.interfaces.js';
|
||||||
import {localStorage} from '../local.js';
|
import {localStorage} from '../local.js';
|
||||||
import {options} from '../options.js';
|
import {options} from '../options.js';
|
||||||
@@ -160,8 +161,8 @@ export class CompilerOverridesWidget {
|
|||||||
btn.addClass('active');
|
btn.addClass('active');
|
||||||
} else if (state instanceof IncompatibleState) {
|
} else if (state instanceof IncompatibleState) {
|
||||||
btn.prop('disabled', true);
|
btn.prop('disabled', true);
|
||||||
btn.prop('data-toggle', 'tooltip');
|
btn.prop('data-bs-toggle', 'tooltip');
|
||||||
btn.prop('data-placement', 'top');
|
btn.prop('data-bs-placement', 'top');
|
||||||
btn.prop('title', state.reason);
|
btn.prop('title', state.reason);
|
||||||
}
|
}
|
||||||
div.data('ov-name', fave.name);
|
div.data('ov-name', fave.name);
|
||||||
@@ -416,9 +417,8 @@ export class CompilerOverridesWidget {
|
|||||||
|
|
||||||
const lastOverrides = JSON.stringify(this.configured);
|
const lastOverrides = JSON.stringify(this.configured);
|
||||||
|
|
||||||
const popup = this.popupDomRoot.modal();
|
|
||||||
// popup is shared, so clear the events first
|
// popup is shared, so clear the events first
|
||||||
popup.off('hidden.bs.modal').on('hidden.bs.modal', () => {
|
BootstrapUtils.setElementEventHandler(this.popupDomRoot, 'hidden.bs.modal', () => {
|
||||||
this.configured = this.loadStateFromUI();
|
this.configured = this.loadStateFromUI();
|
||||||
|
|
||||||
const newOverrides = JSON.stringify(this.configured);
|
const newOverrides = JSON.stringify(this.configured);
|
||||||
@@ -428,5 +428,7 @@ export class CompilerOverridesWidget {
|
|||||||
this.onChangeCallback();
|
this.onChangeCallback();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BootstrapUtils.showModal(this.popupDomRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import * as sifter from '@orchidjs/sifter';
|
|||||||
import {escapeHTML, intersection, remove, unique} from '../../shared/common-utils.js';
|
import {escapeHTML, intersection, remove, unique} from '../../shared/common-utils.js';
|
||||||
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
||||||
import {unwrap, unwrapString} from '../assert.js';
|
import {unwrap, unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {CompilerService} from '../compiler-service.js';
|
import {CompilerService} from '../compiler-service.js';
|
||||||
import {highlight} from '../highlight.js';
|
import {highlight} from '../highlight.js';
|
||||||
import {CompilerPicker} from './compiler-picker.js';
|
import {CompilerPicker} from './compiler-picker.js';
|
||||||
@@ -64,7 +65,7 @@ export class CompilerPickerPopup {
|
|||||||
this.categoryFilters = [];
|
this.categoryFilters = [];
|
||||||
this.searchBar.val('');
|
this.searchBar.val('');
|
||||||
|
|
||||||
this.modal.on('shown.bs.modal', () => {
|
BootstrapUtils.setElementEventHandler(this.modal, 'shown.bs.modal', () => {
|
||||||
this.searchBar[0].focus();
|
this.searchBar[0].focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,7 @@ export class CompilerPickerPopup {
|
|||||||
`
|
`
|
||||||
<div class="compiler d-flex" data-value="${compiler.id}">
|
<div class="compiler d-flex" data-value="${compiler.id}">
|
||||||
<div>${searchRegexes ? highlight(name, searchRegexes) : name}</div>
|
<div>${searchRegexes ? highlight(name, searchRegexes) : name}</div>
|
||||||
<div title="Click to mark or unmark as a favorite" class="ml-auto toggle-fav">
|
<div title="Click to mark or unmark as a favorite" class="ms-auto toggle-fav">
|
||||||
<i class="${extraClasses}"></i>
|
<i class="${extraClasses}"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -264,10 +265,10 @@ export class CompilerPickerPopup {
|
|||||||
show() {
|
show() {
|
||||||
this.searchBar.trigger('input');
|
this.searchBar.trigger('input');
|
||||||
this.fillCompilers();
|
this.fillCompilers();
|
||||||
this.modal.modal({});
|
BootstrapUtils.showModal(this.modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.modal.modal('hide');
|
BootstrapUtils.hideModal(this.modal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export class CompilerPicker {
|
|||||||
'<div class="d-flex"><div>' +
|
'<div class="d-flex"><div>' +
|
||||||
escapeHtml(data.name) +
|
escapeHtml(data.name) +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div title="Click to mark or unmark as a favorite" class="ml-auto toggle-fav">' +
|
'<div title="Click to mark or unmark as a favorite" class="ms-auto toggle-fav">' +
|
||||||
'<i class="' +
|
'<i class="' +
|
||||||
extraClasses +
|
extraClasses +
|
||||||
'"></i>' +
|
'"></i>' +
|
||||||
@@ -143,6 +143,7 @@ export class CompilerPicker {
|
|||||||
'</div>'
|
'</div>'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
item: (data, escapeHtml) => `<div title="${escapeHtml(data.name)}">${escapeHtml(data.name)}</div>`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {escapeHTML} from '../../shared/common-utils.js';
|
import {escapeHTML} from '../../shared/common-utils.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {options} from '../options.js';
|
import {options} from '../options.js';
|
||||||
|
|
||||||
export type CompilerVersionInfo = {version: string; fullVersion?: string};
|
export type CompilerVersionInfo = {version: string; fullVersion?: string};
|
||||||
@@ -78,14 +79,19 @@ function reallySetCompilerVersionPopover(
|
|||||||
.on('click', () => {
|
.on('click', () => {
|
||||||
versionContent.toggle();
|
versionContent.toggle();
|
||||||
hiddenVersionText.toggle();
|
hiddenVersionText.toggle();
|
||||||
pane.fullCompilerName.popover('update');
|
const popover = BootstrapUtils.getPopoverInstance(pane.fullCompilerName);
|
||||||
|
if (popover) popover.update();
|
||||||
});
|
});
|
||||||
hiddenSection.append(hiddenVersionText).append(clickToExpandContent);
|
hiddenSection.append(hiddenVersionText).append(clickToExpandContent);
|
||||||
bodyContent.append(hiddenSection);
|
bodyContent.append(hiddenSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.fullCompilerName.popover('dispose');
|
// Dispose of existing popover
|
||||||
pane.fullCompilerName.popover({
|
const existingPopover = BootstrapUtils.getPopoverInstance(pane.fullCompilerName);
|
||||||
|
if (existingPopover) existingPopover.dispose();
|
||||||
|
|
||||||
|
// Initialize new popover
|
||||||
|
BootstrapUtils.initPopover(pane.fullCompilerName, {
|
||||||
html: true,
|
html: true,
|
||||||
title: notification
|
title: notification
|
||||||
? ($.parseHTML('<span>Compiler Version: ' + notification + '</span>')[0] as Element)
|
? ($.parseHTML('<span>Compiler Version: ' + notification + '</span>')[0] as Element)
|
||||||
|
|||||||
@@ -47,11 +47,7 @@ function makeFontSizeDropdown(elem: JQuery, obj: FontScale, buttonDropdown: JQue
|
|||||||
for (let i = 8; i <= 30; i++) {
|
for (let i = 8; i <= 30; i++) {
|
||||||
const item = $('<button></button>');
|
const item = $('<button></button>');
|
||||||
|
|
||||||
item.attr('data-value', i)
|
item.attr('data-value', i).addClass('dropdown-item').text(i).appendTo(elem).on('click', onClickEvent);
|
||||||
.addClass('dropdown-item btn btn-sm btn-light')
|
|
||||||
.text(i)
|
|
||||||
.appendTo(elem)
|
|
||||||
.on('click', onClickEvent);
|
|
||||||
|
|
||||||
if (obj.scale === i) {
|
if (obj.scale === i) {
|
||||||
item.addClass('active');
|
item.addClass('active');
|
||||||
|
|||||||
@@ -25,9 +25,10 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {editor} from 'monaco-editor';
|
import {editor} from 'monaco-editor';
|
||||||
import {pluck} from 'underscore';
|
import {pluck} from 'underscore';
|
||||||
|
import {unwrap} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {EditorSource, HistoryEntry, sortedList} from '../history.js';
|
import {EditorSource, HistoryEntry, sortedList} from '../history.js';
|
||||||
import ITextModel = editor.ITextModel;
|
import ITextModel = editor.ITextModel;
|
||||||
import {unwrap} from '../assert.js';
|
|
||||||
|
|
||||||
type Entry = {dt: number; name: string; load: () => void};
|
type Entry = {dt: number; name: string; load: () => void};
|
||||||
|
|
||||||
@@ -72,7 +73,9 @@ export class HistoryWidget {
|
|||||||
name: `${dt.replace(/\s\(.*\)/, '')} (${languages})`,
|
name: `${dt.replace(/\s\(.*\)/, '')} (${languages})`,
|
||||||
load: () => {
|
load: () => {
|
||||||
this.onLoad(data);
|
this.onLoad(data);
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
@@ -140,7 +143,8 @@ export class HistoryWidget {
|
|||||||
this.onLoadCallback = onLoad;
|
this.onLoadCallback = onLoad;
|
||||||
|
|
||||||
// It can't tell that we initialize modal on initializeIfNeeded, so it sticks to the possibility of it being null
|
// It can't tell that we initialize modal on initializeIfNeeded, so it sticks to the possibility of it being null
|
||||||
unwrap(this.modal).on('shown.bs.modal', () => this.resizeLayout());
|
const modalElement = unwrap(this.modal)[0];
|
||||||
unwrap(this.modal).modal();
|
modalElement.addEventListener('shown.bs.modal', () => this.resizeLayout());
|
||||||
|
BootstrapUtils.showModal(modalElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {unwrapString} from '../assert.js';
|
import {unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {localStorage} from '../local.js';
|
import {localStorage} from '../local.js';
|
||||||
import {Library, LibraryVersion} from '../options.interfaces.js';
|
import {Library, LibraryVersion} from '../options.interfaces.js';
|
||||||
import {options} from '../options.js';
|
import {options} from '../options.js';
|
||||||
@@ -187,8 +188,7 @@ export class LibsWidget {
|
|||||||
this.domRoot.addClass('mobile');
|
this.domRoot.addClass('mobile');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.domRoot
|
BootstrapUtils.setElementEventHandler(this.domRoot, 'shown.bs.modal', () => {
|
||||||
.on('shown.bs.modal', () => {
|
|
||||||
searchInput.trigger('focus');
|
searchInput.trigger('focus');
|
||||||
|
|
||||||
for (const filter of this.filters) {
|
for (const filter of this.filters) {
|
||||||
@@ -202,8 +202,9 @@ export class LibsWidget {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.on('hide.bs.modal', () => {
|
|
||||||
|
BootstrapUtils.setElementEventHandler(this.domRoot, 'hide.bs.modal', () => {
|
||||||
this.hidePopups();
|
this.hidePopups();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -212,7 +213,7 @@ export class LibsWidget {
|
|||||||
this.domRoot.find('.lib-search-button').on('click', this.startSearching.bind(this));
|
this.domRoot.find('.lib-search-button').on('click', this.startSearching.bind(this));
|
||||||
|
|
||||||
this.dropdownButton.on('click', () => {
|
this.dropdownButton.on('click', () => {
|
||||||
this.domRoot.modal({});
|
BootstrapUtils.showModal(this.domRoot);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.updateButton();
|
this.updateButton();
|
||||||
@@ -342,11 +343,14 @@ export class LibsWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hidePopups() {
|
hidePopups() {
|
||||||
this.searchResults.find('.lib-info-button').popover('hide');
|
this.searchResults.find('.lib-info-button').each((_, el) => BootstrapUtils.hidePopover($(el)));
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSearchResults() {
|
clearSearchResults() {
|
||||||
this.searchResults.find('.lib-info-button').popover('dispose');
|
this.searchResults.find('.lib-info-button').each((_, el) => {
|
||||||
|
const popover = BootstrapUtils.getPopoverInstance($(el));
|
||||||
|
if (popover) popover.dispose();
|
||||||
|
});
|
||||||
this.searchResults.html('');
|
this.searchResults.html('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,7 +502,7 @@ export class LibsWidget {
|
|||||||
'<div class="arrow"></div>' +
|
'<div class="arrow"></div>' +
|
||||||
'<h3 class="popover-header"></h3><div class="popover-body"></div>' +
|
'<h3 class="popover-header"></h3><div class="popover-body"></div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
infoButton.popover({
|
BootstrapUtils.initPopover(infoButton, {
|
||||||
html: true,
|
html: true,
|
||||||
title: 'Build info for ' + getCompilerName(this.currentCompilerId),
|
title: 'Build info for ' + getCompilerName(this.currentCompilerId),
|
||||||
content: () => {
|
content: () => {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {escapeHTML} from '../../shared/common-utils.js';
|
|||||||
import {Language} from '../../types/languages.interfaces.js';
|
import {Language} from '../../types/languages.interfaces.js';
|
||||||
import {SourceApiEntry} from '../../types/source.interfaces.js';
|
import {SourceApiEntry} from '../../types/source.interfaces.js';
|
||||||
import {unwrap, unwrapString} from '../assert.js';
|
import {unwrap, unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {HistorySource} from '../history.js';
|
import {HistorySource} from '../history.js';
|
||||||
import {localStorage} from '../local.js';
|
import {localStorage} from '../local.js';
|
||||||
import {Alert} from './alert.js';
|
import {Alert} from './alert.js';
|
||||||
@@ -98,7 +99,9 @@ export class LoadSave {
|
|||||||
window.location.origin + this.base + 'source/builtin/load/' + element.lang + '/' + element.file,
|
window.location.origin + this.base + 'source/builtin/load/' + element.lang + '/' + element.file,
|
||||||
response => this.onLoad(response.file),
|
response => this.onLoad(response.file),
|
||||||
);
|
);
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static populate(root: JQuery, list: PopulateItem[]) {
|
private static populate(root: JQuery, list: PopulateItem[]) {
|
||||||
@@ -143,7 +146,9 @@ export class LoadSave {
|
|||||||
name: name,
|
name: name,
|
||||||
load: () => {
|
load: () => {
|
||||||
this.onLoad(data);
|
this.onLoad(data);
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
delete: () => {
|
delete: () => {
|
||||||
this.alertSystem.ask(
|
this.alertSystem.ask(
|
||||||
@@ -183,7 +188,9 @@ export class LoadSave {
|
|||||||
name: dt.replace(/\s\(.*\)/, ''),
|
name: dt.replace(/\s\(.*\)/, ''),
|
||||||
load: () => {
|
load: () => {
|
||||||
this.onLoad(data.source);
|
this.onLoad(data.source);
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
@@ -214,7 +221,9 @@ export class LoadSave {
|
|||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
}
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(onLoad, editorText, currentLanguage: Language) {
|
public run(onLoad, editorText, currentLanguage: Language) {
|
||||||
@@ -224,7 +233,11 @@ export class LoadSave {
|
|||||||
this.populateLocalHistory();
|
this.populateLocalHistory();
|
||||||
this.onLoadCallback = onLoad;
|
this.onLoadCallback = onLoad;
|
||||||
unwrap(this.modal).find('.local-file').attr('accept', currentLanguage.extensions.join(','));
|
unwrap(this.modal).find('.local-file').attr('accept', currentLanguage.extensions.join(','));
|
||||||
this.populateBuiltins().then(() => this.modal?.modal());
|
this.populateBuiltins().then(() => {
|
||||||
|
if (this.modal) {
|
||||||
|
BootstrapUtils.showModal(this.modal);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onSaveToBrowserStorage() {
|
private onSaveToBrowserStorage() {
|
||||||
@@ -238,7 +251,9 @@ export class LoadSave {
|
|||||||
LoadSave.setLocalFile(name, this.editorText);
|
LoadSave.setLocalFile(name, this.editorText);
|
||||||
};
|
};
|
||||||
if (name in LoadSave.getLocalFiles()) {
|
if (name in LoadSave.getLocalFiles()) {
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
this.alertSystem.ask(
|
this.alertSystem.ask(
|
||||||
'Replace current?',
|
'Replace current?',
|
||||||
`Do you want to replace the existing saved file '${escapeHTML(name)}'?`,
|
`Do you want to replace the existing saved file '${escapeHTML(name)}'?`,
|
||||||
@@ -246,7 +261,9 @@ export class LoadSave {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
doneCallback();
|
doneCallback();
|
||||||
this.modal?.modal('hide');
|
if (this.modal) {
|
||||||
|
BootstrapUtils.hideModal(this.modal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
RuntimeToolType,
|
RuntimeToolType,
|
||||||
} from '../../types/execution/execution.interfaces.js';
|
} from '../../types/execution/execution.interfaces.js';
|
||||||
import {assert} from '../assert.js';
|
import {assert} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {CompilerInfo} from '../compiler.interfaces.js';
|
import {CompilerInfo} from '../compiler.interfaces.js';
|
||||||
import {localStorage} from '../local.js';
|
import {localStorage} from '../local.js';
|
||||||
import {options} from '../options.js';
|
import {options} from '../options.js';
|
||||||
@@ -392,9 +393,8 @@ export class RuntimeToolsWidget {
|
|||||||
|
|
||||||
const lastOverrides = JSON.stringify(this.configured);
|
const lastOverrides = JSON.stringify(this.configured);
|
||||||
|
|
||||||
const popup = this.popupDomRoot.modal();
|
|
||||||
// popup is shared, so clear the events first
|
// popup is shared, so clear the events first
|
||||||
popup.off('hidden.bs.modal').on('hidden.bs.modal', () => {
|
BootstrapUtils.setElementEventHandler(this.popupDomRoot, 'hidden.bs.modal', () => {
|
||||||
this.configured = this.loadStateFromUI();
|
this.configured = this.loadStateFromUI();
|
||||||
|
|
||||||
const newOverrides = JSON.stringify(this.configured);
|
const newOverrides = JSON.stringify(this.configured);
|
||||||
@@ -404,5 +404,7 @@ export class RuntimeToolsWidget {
|
|||||||
this.onChangeCallback();
|
this.onChangeCallback();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BootstrapUtils.showModal(this.popupDomRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import GoldenLayout from 'golden-layout';
|
|||||||
import {escapeHTML} from '../../shared/common-utils.js';
|
import {escapeHTML} from '../../shared/common-utils.js';
|
||||||
import {SiteTemplateResponse, UserSiteTemplate} from '../../types/features/site-templates.interfaces.js';
|
import {SiteTemplateResponse, UserSiteTemplate} from '../../types/features/site-templates.interfaces.js';
|
||||||
import {assert, unwrap, unwrapString} from '../assert.js';
|
import {assert, unwrap, unwrapString} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
import {localStorage} from '../local.js';
|
import {localStorage} from '../local.js';
|
||||||
import {Settings} from '../settings.js';
|
import {Settings} from '../settings.js';
|
||||||
import * as url from '../url.js';
|
import * as url from '../url.js';
|
||||||
@@ -174,7 +175,7 @@ class SiteTemplatesWidget {
|
|||||||
this.populated = true;
|
this.populated = true;
|
||||||
}
|
}
|
||||||
show() {
|
show() {
|
||||||
this.modal.modal('show');
|
BootstrapUtils.showModal(this.modal);
|
||||||
if (!this.populated) {
|
if (!this.populated) {
|
||||||
this.populate();
|
this.populate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,12 @@
|
|||||||
|
|
||||||
import {Chart, ChartData, defaults} from 'chart.js';
|
import {Chart, ChartData, defaults} from 'chart.js';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {Settings} from '../settings.js';
|
|
||||||
import 'chart.js/auto';
|
|
||||||
import {isString} from '../../shared/common-utils.js';
|
import {isString} from '../../shared/common-utils.js';
|
||||||
import {CompilationResult} from '../../types/compilation/compilation.interfaces.js';
|
import {CompilationResult} from '../../types/compilation/compilation.interfaces.js';
|
||||||
import {unwrap} from '../assert.js';
|
import {unwrap} from '../assert.js';
|
||||||
|
import * as BootstrapUtils from '../bootstrap-utils.js';
|
||||||
|
import {Settings} from '../settings.js';
|
||||||
|
import 'chart.js/auto';
|
||||||
|
|
||||||
type Data = ChartData<'bar', number[], string> & {steps: number};
|
type Data = ChartData<'bar', number[], string> & {steps: number};
|
||||||
|
|
||||||
@@ -188,7 +189,7 @@ function displayData(data: Data) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
modal.modal('show');
|
BootstrapUtils.showModal(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function displayCompilationTiming(compileResult: CompilationResult | null, totalTime: number) {
|
export function displayCompilationTiming(compileResult: CompilationResult | null, totalTime: number) {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ block content
|
|||||||
div.ces-item-description= level.description
|
div.ces-item-description= level.description
|
||||||
.ces-top
|
.ces-top
|
||||||
each sponsor in level.sponsors
|
each sponsor in level.sponsors
|
||||||
.ces
|
.ces.d-grid
|
||||||
button.btn-block.btn-secondary(title=sponsor.title onclick=sponsor.onclick disabled=!sponsor.url style=sponsor.style)
|
button.btn.btn-secondary(title=sponsor.title onclick=sponsor.onclick disabled=!sponsor.url style=sponsor.style)
|
||||||
if sponsor.displayType === 'SideBySide'
|
if sponsor.displayType === 'SideBySide'
|
||||||
.d-flex
|
.d-flex
|
||||||
.ces-item-title
|
.ces-item-title
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.btn-group.btn-group-sm(role="group" aria-label="Font size")
|
.btn-group.btn-group-sm(role="group" aria-label="Font size")
|
||||||
button.dropdown-toggle.btn.btn-light.fs-button(type="button" title="Change font size\nTip #1: You can use scroll wheel while hovering over this button\nTip #2: You can ctrl+click this button to reset to default" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-flip="false" data-boundary="viewport")
|
button.dropdown-toggle.btn.btn-light.fs-button(type="button" title="Change font size\nTip #1: You can use scroll wheel while hovering over this button\nTip #2: You can ctrl+click this button to reset to default" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-flip="false" data-bs-boundary="viewport")
|
||||||
span.fa.fa-font #[b.caret]
|
span.fa.fa-font #[b.caret]
|
||||||
.dropdown-menu.font-size-list(aria-labelledby="fs-button")
|
.dropdown-menu.font-size-list(aria-labelledby="fs-button")
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ extends _layout.pug
|
|||||||
|
|
||||||
block prepend content
|
block prepend content
|
||||||
nav.navbar.navbar-godbolt.navbar-expand-md.navbar-light.bg-light
|
nav.navbar.navbar-godbolt.navbar-expand-md.navbar-light.bg-light
|
||||||
|
.container-fluid
|
||||||
include logo.pug
|
include logo.pug
|
||||||
button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation")
|
button.navbar-toggler(type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation")
|
||||||
span.navbar-toggler-icon
|
span.navbar-toggler-icon
|
||||||
.collapse.navbar-collapse#navbarContent
|
.collapse.navbar-collapse#navbarContent
|
||||||
ul.navbar-nav.navbar-left.mr-auto
|
ul.navbar-nav.me-auto.mb-2.mb-md-0
|
||||||
li.nav-item.dropdown
|
li.nav-item.dropdown
|
||||||
button.btn.btn-light.nav-link.dropdown-toggle#addDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Add...
|
button.btn.btn-light.nav-link.dropdown-toggle#addDropdown(role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Add...
|
||||||
div.dropdown-menu(aria-labelledby="addDropdown")
|
div.dropdown-menu(aria-labelledby="addDropdown")
|
||||||
button.dropdown-item.btn#add-editor(title="Click or drag to desired destination")
|
button.dropdown-item.btn#add-editor(title="Click or drag to desired destination")
|
||||||
span.dropdown-icon.fa.fa-code
|
span.dropdown-icon.fa.fa-code
|
||||||
@@ -20,9 +21,9 @@ block prepend content
|
|||||||
span.dropdown-icon.fa.fa-list-alt
|
span.dropdown-icon.fa.fa-list-alt
|
||||||
| Tree (IDE Mode)
|
| Tree (IDE Mode)
|
||||||
li.nav-item.dropdown
|
li.nav-item.dropdown
|
||||||
button.btn.btn-light.nav-link.dropdown-toggle#moreDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="more-dropdown-btn") More
|
button.btn.btn-light.nav-link.dropdown-toggle#moreDropdown(role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="more-dropdown-btn") More
|
||||||
div.dropdown-menu(aria-labelledby="moreDropdown")
|
div.dropdown-menu(aria-labelledby="moreDropdown")
|
||||||
button.dropdown-item.btn#setting(data-target="#settings" data-toggle="modal")
|
button.dropdown-item.btn#setting(data-bs-target="#settings" data-bs-toggle="modal")
|
||||||
span.dropdown-icon.fas.fa-sliders-h
|
span.dropdown-icon.fas.fa-sliders-h
|
||||||
| Settings
|
| Settings
|
||||||
div.dropdown-divider
|
div.dropdown-divider
|
||||||
@@ -60,47 +61,52 @@ block prepend content
|
|||||||
a.nav-link.ui-presentation-next(href="javascript:;")
|
a.nav-link.ui-presentation-next(href="javascript:;")
|
||||||
span.dropdown-icon.fas.fa-forward
|
span.dropdown-icon.fas.fa-forward
|
||||||
| Next
|
| Next
|
||||||
ul#motd.navbar-nav.navbar-left.mr-auto.community-advert.d-none
|
|
||||||
|
ul#motd.navbar-nav.community-advert.d-none.mx-auto
|
||||||
span.content
|
span.content
|
||||||
| Thanks for using Compiler Explorer
|
| Thanks for using Compiler Explorer
|
||||||
span.community-hide(title="Hide and never show again" aria-label="Close")
|
span.community-hide(title="Hide and never show again" aria-label="Close")
|
||||||
button.close(type="button" aria-hidden="true") ×
|
button.btn-close(type="button" aria-label="Close")
|
||||||
ul.navbar-nav.navbar-right
|
|
||||||
|
ul.navbar-nav.ms-auto.mb-2.mb-md-0
|
||||||
if showSponsors
|
if showSponsors
|
||||||
li.nav-item.btn.btn-outline-info#ces(data-toggle="modal")
|
li.nav-item.btn.btn-outline-info#ces
|
||||||
span#ces-banner-text Sponsors
|
span#ces-banner-text Sponsors
|
||||||
include sponsor-icons.pug
|
include sponsor-icons.pug
|
||||||
li.nav-item.dropdown
|
li.nav-item.dropdown#share-tooltip-target
|
||||||
button.btn.btn-light.nav-link.dropdown-toggle#share(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Share
|
button.btn.btn-light.nav-link.dropdown-toggle#share(role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Share
|
||||||
div.dropdown-menu.dropdown-menu-right
|
div.dropdown-menu.dropdown-menu-end
|
||||||
|
// In order for these to support both the clipboard button _and_ optionally opening the dialog, we can't
|
||||||
|
// use `data-bs-toggle="modal"` on the `<a>` itself, as that would prevent the clipboard button from working.
|
||||||
|
// Bootstrap's default blanket event handler beats out any event handler we manually attach to the button.
|
||||||
if storageSolution !== "null"
|
if storageSolution !== "null"
|
||||||
a.dropdown-item#shareShort(href="javascript:;" data-target="#sharelinkdialog" data-toggle="modal" data-bind="Short")
|
a.dropdown-item#shareShort(href="javascript:;" data-bs-target="#sharelinkdialog" data-bind="Short")
|
||||||
span.dropdown-icon.fas.fa-cloud.d-inline
|
span.dropdown-icon.fas.fa-cloud.d-inline
|
||||||
| Short Link
|
| Short Link
|
||||||
button.btn.btn-sm.copy-link-btn.clip-icon.float-right(data-toggle="none")
|
button.btn.btn-sm.copy-link-btn.clip-icon.float-end(data-bs-target="" data-bs-toggle="none")
|
||||||
span.dropdown-icon.fa.fa-clipboard
|
span.dropdown-icon.fa.fa-clipboard
|
||||||
a.dropdown-item#shareFull(href="javascript:;" data-target="#sharelinkdialog" data-toggle="modal" data-bind="Full")
|
a.dropdown-item#shareFull(href="javascript:;" data-bs-target="#sharelinkdialog" data-bind="Full")
|
||||||
span.dropdown-icon.fas.fa-store-slash.d-inline
|
span.dropdown-icon.fas.fa-store-slash.d-inline
|
||||||
| Full Link
|
| Full Link
|
||||||
button.btn.btn-sm.copy-link-btn.clip-icon.float-right(data-toggle="none")
|
button.btn.btn-sm.copy-link-btn.clip-icon.float-end(data-bs-toggle="none")
|
||||||
span.dropdown-icon.fa.fa-clipboard
|
span.dropdown-icon.fa.fa-clipboard
|
||||||
a.dropdown-item#shareEmbed(href="javascript:;" data-target="#sharelinkdialog" data-toggle="modal" data-bind="Embed")
|
a.dropdown-item#shareEmbed(href="javascript:;" data-bs-target="#sharelinkdialog" data-bind="Embed")
|
||||||
span.dropdown-icon.fas.fa-window-restore.d-inline
|
span.dropdown-icon.fas.fa-window-restore.d-inline
|
||||||
| Embed in iframe
|
| Embed in iframe
|
||||||
// This is not an oversight, there is in fact a .float-right missing here that's there in the other 2
|
// This is not an oversight, there is in fact a .float-end missing here that's there in the other 2
|
||||||
button.btn.btn-sm.copy-link-btn.clip-icon(data-toggle="none")
|
button.btn.btn-sm.copy-link-btn.clip-icon(data-bs-toggle="none")
|
||||||
span.dropdown-icon.fa.fa-clipboard
|
span.dropdown-icon.fa.fa-clipboard
|
||||||
if policies.cookies.enabled || policies.privacy.enabled
|
if policies.cookies.enabled || policies.privacy.enabled
|
||||||
li.nav-item.dropdown
|
li.nav-item.dropdown
|
||||||
button.btn.btn-light.nav-link.dropdown-toggle#policiesDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
button.btn.btn-light.nav-link.dropdown-toggle#policiesDropdown(role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
| Policies
|
| Policies
|
||||||
span#policyBellNotification.d-none.badge.badge-pill.badge-primary
|
span#policyBellNotification.d-none.badge.rounded-pill.bg-primary
|
||||||
span.fa.fa-bell
|
span.fa.fa-bell
|
||||||
div.dropdown-menu.dropdown-menu-right(aria-labelledby="policiesDropdown")
|
div.dropdown-menu.dropdown-menu-end(aria-labelledby="policiesDropdown")
|
||||||
include menu-policies.pug
|
include menu-policies.pug
|
||||||
li.nav-item.dropdown
|
li.nav-item.dropdown
|
||||||
button.btn.btn-light.nav-link.dropdown-toggle#otherDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Other
|
button.btn.btn-light.nav-link.dropdown-toggle#otherDropdown(role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Other
|
||||||
div.dropdown-menu.dropdown-menu-right(aria-labelledby="otherDropdown")
|
div.dropdown-menu.dropdown-menu-end(aria-labelledby="otherDropdown")
|
||||||
include menu-other.pug
|
include menu-other.pug
|
||||||
|
|
||||||
block append footer
|
block append footer
|
||||||
@@ -108,5 +114,4 @@ block append footer
|
|||||||
#real-dark
|
#real-dark
|
||||||
#true-dark
|
#true-dark
|
||||||
.content Try the real dark theme 🔦
|
.content Try the real dark theme 🔦
|
||||||
.close
|
button.btn.dark-close.fas.fa-times(type="button" aria-label="Close")
|
||||||
i.fa-solid.fa-xmark
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
button.dropdown-item.btn#cookies
|
button.dropdown-item.btn#cookies
|
||||||
span.dropdown-icon.fas.fa-cookie-bite
|
span.dropdown-icon.fas.fa-cookie-bite
|
||||||
| Cookie policy
|
| Cookie policy
|
||||||
span#cookiesBellNotification.d-none.badge.badge-pill.badge-primary
|
span#cookiesBellNotification.d-none.badge.rounded-pill.bg-primary
|
||||||
span.fa.fa-bell
|
span.fa.fa-bell
|
||||||
button.dropdown-item.btn#privacy
|
button.dropdown-item.btn#privacy
|
||||||
span.dropdown-icon.fas.fa-user-lock
|
span.dropdown-icon.fas.fa-user-lock
|
||||||
| Privacy policy
|
| Privacy policy
|
||||||
span#privacyBellNotification.d-none.badge.badge-pill.badge-primary
|
span#privacyBellNotification.d-none.badge.rounded-pill.bg-primary
|
||||||
span.fa.fa-bell
|
span.fa.fa-bell
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ block content
|
|||||||
input#filterAnsi(name='filterAnsi' value='true' type='hidden')
|
input#filterAnsi(name='filterAnsi' value='true' type='hidden')
|
||||||
|
|
||||||
.form-pair.inlined.dropdown
|
.form-pair.inlined.dropdown
|
||||||
a.btn.nodropdown-toggle#outputDropdown(href="javascript:;" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
a.btn.nodropdown-toggle#outputDropdown(href="javascript:;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.fas.fa-cog
|
span.fas.fa-cog
|
||||||
| Output
|
| Output
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ block content
|
|||||||
include ../options-output.pug
|
include ../options-output.pug
|
||||||
|
|
||||||
.form-pair.inlined.dropdown
|
.form-pair.inlined.dropdown
|
||||||
a.btn.nodropdown-toggle#filtersDropdown(href="javascript:;" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
a.btn.nodropdown-toggle#filtersDropdown(href="javascript:;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.fas.fa-filter
|
span.fas.fa-filter
|
||||||
| Filters
|
| Filters
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
block footer
|
block footer
|
||||||
nav.bg-light
|
nav.bg-light
|
||||||
if mobileViewer
|
if mobileViewer
|
||||||
a.btn.nodropdown-toggle#otherDropdown(href="javascript:;" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Other
|
a.btn.nodropdown-toggle#otherDropdown(href="javascript:;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Other
|
||||||
|
|
||||||
.noscriptdropdown(aria-labelledby="otherDropdown")
|
.noscriptdropdown(aria-labelledby="otherDropdown")
|
||||||
include ../menu-other.pug
|
include ../menu-other.pug
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
.header
|
.header
|
||||||
nav.navbar.navbar-godbolt.navbar-expand-md.navbar-light.bg-light
|
nav.navbar.navbar-godbolt.navbar-expand-md.navbar-light.bg-light
|
||||||
include ../logo.pug
|
include ../logo.pug
|
||||||
#motd.navbar-nav.navbar-center.mr-auto.community-advert.d-none
|
#motd.navbar-nav.navbar-center.me-auto.community-advert.d-none
|
||||||
span.content
|
span.content
|
||||||
| Thanks for using Compiler Explorer
|
| Thanks for using Compiler Explorer
|
||||||
.navbar-nav.navbar-right
|
.navbar-nav.navbar-right
|
||||||
if showSponsors
|
if showSponsors
|
||||||
li.nav-item.btn.btn-outline-primary#ces(data-toggle="modal")
|
li.nav-item.btn.btn-outline-primary#ces(data-bs-toggle="modal")
|
||||||
a(href=`${httpRoot}noscript/sponsors`) Sponsors
|
a(href=`${httpRoot}noscript/sponsors`) Sponsors
|
||||||
include ../sponsor-icons.pug
|
include ../sponsor-icons.pug
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
block header
|
block header
|
||||||
nav.bg-light
|
nav.bg-light
|
||||||
if mobileViewer
|
if mobileViewer
|
||||||
a.btn.nodropdown-toggle#languageDropdown(href="javascript:;" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Language
|
a.btn.nodropdown-toggle#languageDropdown(href="javascript:;" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Language
|
||||||
|
|
||||||
.noscriptdropdown(aria-labelledby="languageDropdown")
|
.noscriptdropdown(aria-labelledby="languageDropdown")
|
||||||
each language in languages
|
each language in languages
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Something alert worthy
|
h5.modal-title Something alert worthy
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal" data-cy="close-alert-btn") Close
|
button.btn.btn-outline-primary(type="button" data-bs-dismiss="modal" data-cy="close-alert-btn") Close
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Compilers
|
h5.modal-title Compilers
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
|
|||||||
@@ -3,12 +3,11 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Enter something here
|
h5.modal-title Enter something here
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.question
|
.mb-3
|
||||||
input.question-answer
|
label.form-label.question
|
||||||
|
input.form-control.question-answer
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-light.no(type="button" data-dismiss="modal") Cancel
|
button.btn.btn-light.no(type="button" data-bs-dismiss="modal") Cancel
|
||||||
button.btn.btn-light.yes(type="button" data-dismiss="modal") Ok
|
button.btn.btn-light.yes(type="button" data-bs-dismiss="modal") Ok
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title History
|
h5.modal-title History
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
@@ -18,4 +16,4 @@
|
|||||||
div.src-content#load-history-src-display(style="height:600px;overflow-y:scroll;flex:2")
|
div.src-content#load-history-src-display(style="height:600px;overflow-y:scroll;flex:2")
|
||||||
div.monaco-placeholder
|
div.monaco-placeholder
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close
|
button.btn.btn-outline-primary(type="button" data-bs-dismiss="modal") Close
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Libraries
|
h5.modal-title Libraries
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
@@ -13,7 +11,8 @@
|
|||||||
.row
|
.row
|
||||||
.col-lg
|
.col-lg
|
||||||
div(style='text-align: center')
|
div(style='text-align: center')
|
||||||
input.lib-search-input(value="" placeholder="Search text")
|
.input-group.mb-3
|
||||||
|
input.form-control.lib-search-input(value="" placeholder="Search text")
|
||||||
button.btn.btn-primary.lib-search-button(type="button") Search
|
button.btn.btn-primary.lib-search-button(type="button") Search
|
||||||
hr
|
hr
|
||||||
.row
|
.row
|
||||||
|
|||||||
@@ -3,17 +3,15 @@
|
|||||||
.modal-content(style="max-width: unset")
|
.modal-content(style="max-width: unset")
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Load and save editor text
|
h5.modal-title Load and save editor text
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-header
|
.card-header
|
||||||
ul.nav.nav-tabs.card-header-tabs(role="tablist")
|
ul.nav.nav-tabs.card-header-tabs(role="tablist")
|
||||||
li.nav-item(role="presentation"): a.nav-link.active(href="#load-examples" role="tab" data-toggle="tab") Examples
|
li.nav-item(role="presentation"): a.nav-link.active(href="#load-examples" role="tab" data-bs-toggle="tab") Examples
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#load-browser-local" role="tab" data-toggle="tab") Browser-local storage
|
li.nav-item(role="presentation"): a.nav-link(href="#load-browser-local" role="tab" data-bs-toggle="tab") Browser-local storage
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#load-browser-local-history" role="tab" data-toggle="tab") Browser-local history
|
li.nav-item(role="presentation"): a.nav-link(href="#load-browser-local-history" role="tab" data-bs-toggle="tab") Browser-local history
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#load-file-system" role="tab" data-toggle="tab") File system
|
li.nav-item(role="presentation"): a.nav-link(href="#load-file-system" role="tab" data-bs-toggle="tab") File system
|
||||||
.card-body.tab-content
|
.card-body.tab-content
|
||||||
#load-examples.tab-pane.active(role="tabpanel")
|
#load-examples.tab-pane.active(role="tabpanel")
|
||||||
h4.card-title Load from examples:
|
h4.card-title Load from examples:
|
||||||
@@ -23,16 +21,15 @@
|
|||||||
h4.card-title Load from browser-local storage:
|
h4.card-title Load from browser-local storage:
|
||||||
ul.local-storage.small-v-scrollable
|
ul.local-storage.small-v-scrollable
|
||||||
li.template
|
li.template
|
||||||
a.mr-3(href="javascript:;")
|
a.me-3(href="javascript:;")
|
||||||
button.overwrite.btn.btn-sm.btn-light.mr-1
|
button.overwrite.btn.btn-sm.btn-light.me-1
|
||||||
span.fa.fa-edit.mr-1
|
span.fa.fa-edit.me-1
|
||||||
| Overwrite
|
| Overwrite
|
||||||
button.delete.btn.btn-sm.btn-light
|
button.delete.btn.btn-sm.btn-light
|
||||||
span.fa.fa-trash.mr-1
|
span.fa.fa-trash.me-1
|
||||||
| Delete
|
| Delete
|
||||||
.input-group
|
.input-group.mb-3
|
||||||
input.save-name(type="text" size="20" placeholder="Set name of state")
|
input.form-control.save-name(type="text" placeholder="Set name of state")
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-light.save-button(type="button") Save to browser-local storage
|
button.btn.btn-light.save-button(type="button") Save to browser-local storage
|
||||||
#load-browser-local-history.tab-pane(role="tabpanel")
|
#load-browser-local-history.tab-pane(role="tabpanel")
|
||||||
h4.card-title Load from browser-local history:
|
h4.card-title Load from browser-local history:
|
||||||
@@ -40,9 +37,10 @@
|
|||||||
li.template: a(href="javascript:;")
|
li.template: a(href="javascript:;")
|
||||||
#load-file-system.tab-pane(role="tabpanel")
|
#load-file-system.tab-pane(role="tabpanel")
|
||||||
h4.card-title Load/save to your system
|
h4.card-title Load/save to your system
|
||||||
label.btn.btn-outline-secondary.btn-file(role="button") Load from a local file
|
.mb-3
|
||||||
input.local-file(type="file")
|
label.form-label Load from a local file
|
||||||
label.btn.btn-outline-secondary.btn-file.save-btn(role="button") Save to file
|
input.form-control.local-file(type="file")
|
||||||
input.save-file(type="button")
|
.mb-3
|
||||||
|
button.btn.btn-outline-secondary.save-btn(type="button") Save to file
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal" aria-label="Close") Close
|
button.btn.btn-outline-primary(type="button" data-bs-dismiss="modal" aria-label="Close") Close
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Compiler overrides
|
h5.modal-title Compiler overrides
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
@@ -25,8 +23,8 @@
|
|||||||
span.override-name Compiler environment variables
|
span.override-name Compiler environment variables
|
||||||
.card-body
|
.card-body
|
||||||
span.description One environment variable per line, KEY=VALUE, that will be set during compilation.
|
span.description One environment variable per line, KEY=VALUE, that will be set during compilation.
|
||||||
span.custom-override
|
span
|
||||||
textarea.envvars(cols="30")
|
textarea.form-control.envvars(cols="30", rows="3")
|
||||||
.possible-overrides.items
|
.possible-overrides.items
|
||||||
.overrides-favorites-col.col-md
|
.overrides-favorites-col.col-md
|
||||||
h6 Favorites
|
h6 Favorites
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Rename Pane
|
h5.modal-title Rename Pane
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
@@ -13,5 +11,5 @@
|
|||||||
.input-group
|
.input-group
|
||||||
input#renamepaneinput.form-control.panename(type="text" placeholder="New pane name" size="1024")
|
input#renamepaneinput.form-control.panename(type="text" placeholder="New pane name" size="1024")
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-secondary(type="button" data-dismiss="modal") Close
|
button.btn.btn-outline-secondary(type="button" data-bs-dismiss="modal") Close
|
||||||
button#renamepanesubmit.btn.btn-outline-primary(type="submit" data-dismiss="modal" value="Save Changes") Save Changes
|
button#renamepanesubmit.btn.btn-outline-primary(type="submit" data-bs-dismiss="modal" value="Save Changes") Save Changes
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Runtime tools
|
h5.modal-title Runtime tools
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
@@ -23,8 +21,8 @@
|
|||||||
span.runtimetool-name Runtime environment variables
|
span.runtimetool-name Runtime environment variables
|
||||||
.card-body
|
.card-body
|
||||||
span.description One environment variable per line, KEY=VALUE.
|
span.description One environment variable per line, KEY=VALUE.
|
||||||
span.custom-runtimetool
|
span
|
||||||
textarea.envvars(cols="30")
|
textarea.form-control.envvars(cols="30", rows="3")
|
||||||
.possible-runtimetools.items
|
.possible-runtimetools.items
|
||||||
.runtimetools-favorites-col.col-md
|
.runtimetools-favorites-col.col-md
|
||||||
h6 Favorites
|
h6 Favorites
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
mixin checkbox(cls, text)
|
mixin checkbox(cls, text)
|
||||||
.checkbox
|
.form-check
|
||||||
label
|
input.form-check-input(class=cls type="checkbox" id="settings-checkbox-"+cls)
|
||||||
input(class=cls type="checkbox")
|
label.form-check-label(for="settings-checkbox-"+cls)!= text
|
||||||
!= text
|
|
||||||
|
|
||||||
mixin select(cls, text)
|
mixin select(cls, text)
|
||||||
div
|
.mb-3
|
||||||
label!= text
|
label.form-label(for="settings-select-"+cls)!= text
|
||||||
select(class=cls)
|
select.form-select(class=cls id="settings-select-"+cls)
|
||||||
|
|
||||||
mixin input(cls, type, text, style)
|
mixin input(cls, type, text, style)
|
||||||
div
|
.mb-3
|
||||||
label!= text
|
label.form-label(for="settings-input-"+cls)!= text
|
||||||
input(class=cls type=type style=style)
|
input.form-control(class=cls type=type style=style id="settings-input-"+cls)
|
||||||
|
|
||||||
|
|
||||||
#settings.modal.fade.gl_keep(tabindex="-1" role="dialog")
|
#settings.modal.fade.gl_keep(tabindex="-1" role="dialog")
|
||||||
@@ -21,8 +20,7 @@ mixin input(cls, type, text, style)
|
|||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title
|
h5.modal-title
|
||||||
| Compiler Explorer Settings
|
| Compiler Explorer Settings
|
||||||
button.close(type="button" data-dismiss="modal" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-label="Close")
|
||||||
span(aria-hidden="true") ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-header
|
.card-header
|
||||||
@@ -30,53 +28,54 @@ mixin input(cls, type, text, style)
|
|||||||
| preserved as part of shared URLs, and are persisted locally using browser
|
| preserved as part of shared URLs, and are persisted locally using browser
|
||||||
| local storage.
|
| local storage.
|
||||||
ul.nav.nav-tabs.card-header-tabs(role="tablist")
|
ul.nav.nav-tabs.card-header-tabs(role="tablist")
|
||||||
li.nav-item(role="presentation"): a.nav-link.active(href="#colouring" role="tab" data-toggle="tab") Colouring
|
li.nav-item(role="presentation"): a.nav-link.active(href="#colouring" role="tab" data-bs-toggle="tab") Colouring
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#site-behaviour" role="tab" data-toggle="tab") Site behaviour
|
li.nav-item(role="presentation"): a.nav-link(href="#site-behaviour" role="tab" data-bs-toggle="tab") Site behaviour
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#keybindings" role="tab" data-toggle="tab") Keybindings
|
li.nav-item(role="presentation"): a.nav-link(href="#keybindings" role="tab" data-bs-toggle="tab") Keybindings
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#editor" role="tab" data-toggle="tab") Editor
|
li.nav-item(role="presentation"): a.nav-link(href="#editor" role="tab" data-bs-toggle="tab") Editor
|
||||||
li.nav-item(role="presentation"): a.nav-link(href="#compilation" role="tab" data-toggle="tab") Compilation
|
li.nav-item(role="presentation"): a.nav-link(href="#compilation" role="tab" data-bs-toggle="tab") Compilation
|
||||||
.card-body.tab-content
|
.card-body.tab-content
|
||||||
#colouring.tab-pane.active.form-group(role="group")
|
#colouring.tab-pane.active(role="group")
|
||||||
+select("theme", "Site theme")
|
+select("theme", "Site theme")
|
||||||
+checkbox("colourise", "Colourise lines to show how the source maps to the output")
|
+checkbox("colourise", "Colourise lines to show how the source maps to the output")
|
||||||
+checkbox("alwaysEnableAllSchemes", "Make all colour schemes available regardless of theme")
|
+checkbox("alwaysEnableAllSchemes", "Make all colour schemes available regardless of theme")
|
||||||
+select("colourScheme", "Line highlighting colour scheme")
|
+select("colourScheme", "Line highlighting colour scheme")
|
||||||
#site-behaviour.tab-pane.form-group(role="group")
|
#site-behaviour.tab-pane(role="group")
|
||||||
label
|
.mb-3
|
||||||
| Default language
|
label.form-label(for="settings-select-defaultLanguage") Default language
|
||||||
small(style="margin-left: 3px")
|
small(style="margin-left: 3px")
|
||||||
span.fas.fa-info-circle(title="New editors only (Reset UI to clear yours)" aria-label="New editors only (Reset UI to clear yours)")
|
span.fas.fa-info-circle(title="New editors only (Reset UI to clear yours)" aria-label="New editors only (Reset UI to clear yours)")
|
||||||
select.defaultLanguage
|
select.form-select.defaultLanguage(id="settings-select-defaultLanguage")
|
||||||
+checkbox("keepMultipleTabs", "Keep page status per tab")
|
+checkbox("keepMultipleTabs", "Keep page status per tab")
|
||||||
+checkbox("allowStoreCodeDebug", "Allow my source code to be temporarily stored for diagnostic purposes in the event of an error")
|
+checkbox("allowStoreCodeDebug", "Allow my source code to be temporarily stored for diagnostic purposes in the event of an error")
|
||||||
+checkbox("newEditorLastLang", "Use last selected language when opening new Editors")
|
+checkbox("newEditorLastLang", "Use last selected language when opening new Editors")
|
||||||
+checkbox("enableCommunityAds", "Show community events")
|
+checkbox("enableCommunityAds", "Show community events")
|
||||||
#keybindings.tab-pane.form-group(role="group")
|
#keybindings.tab-pane(role="group")
|
||||||
+checkbox("useVim", "Vim editor mode")
|
+checkbox("useVim", "Vim editor mode")
|
||||||
.the-save-option-to-auto-share
|
.the-save-option-to-auto-share
|
||||||
label
|
mb-3
|
||||||
|
label.form-label(for="settings-checkbox-enableCtrlS")
|
||||||
kbd Ctrl
|
kbd Ctrl
|
||||||
| +
|
| +
|
||||||
kbd S
|
kbd S
|
||||||
| behaviour
|
| behaviour
|
||||||
select.enableCtrlS
|
select.form-select.enableCtrlS(id="settings-checkbox-enableCtrlS")
|
||||||
.checkbox.the-save-option-to-tree-save
|
.form-check.the-save-option-to-tree-save
|
||||||
label
|
input.form-check-input.enableCtrlStree(type="checkbox" id="settings-checkbox-enableCtrlStree")
|
||||||
input.enableCtrlStree(type="checkbox")
|
label.form-check-label(for="settings-checkbox-enableCtrlStree")
|
||||||
| Make
|
| Make
|
||||||
kbd Ctrl
|
kbd Ctrl
|
||||||
| +
|
| +
|
||||||
kbd S
|
kbd S
|
||||||
| include and save the file to a Tree if that's added to the UI
|
| include and save the file to a Tree if that's added to the UI
|
||||||
.checkbox.the-popup-dialog-box-option
|
.form-check.the-popup-dialog-box-option
|
||||||
label
|
input.form-check-input.enableSharingPopover(type="checkbox" id="settings-checkbox-enableSharingPopover")
|
||||||
input.enableSharingPopover(type="checkbox")
|
label.form-check-label(for="settings-checkbox-enableSharingPopover")
|
||||||
| Pop up a dialog box when
|
| Pop up a dialog box when
|
||||||
kbd Ctrl
|
kbd Ctrl
|
||||||
| +
|
| +
|
||||||
kbd S
|
kbd S
|
||||||
| is set to create a short link.
|
| is set to create a short link.
|
||||||
#editor.tab-pane.form-group(role="group")
|
#editor.tab-pane(role="group")
|
||||||
+input("editorsFFont", "text", "Desired Font Family in editors", "width:100%")
|
+input("editorsFFont", "text", "Desired Font Family in editors", "width:100%")
|
||||||
+select("defaultFontScale", "Default font scale")
|
+select("defaultFontScale", "Default font scale")
|
||||||
+checkbox("editorsFLigatures", "Enable font ligatures")
|
+checkbox("editorsFLigatures", "Enable font ligatures")
|
||||||
@@ -97,14 +96,15 @@ mixin input(cls, type, text, style)
|
|||||||
+checkbox("wordWrap", "Enable Word Wrapping")
|
+checkbox("wordWrap", "Enable Word Wrapping")
|
||||||
+checkbox("enableCodeLens", "Enable CodeLens features (requires refresh to take effect)")
|
+checkbox("enableCodeLens", "Enable CodeLens features (requires refresh to take effect)")
|
||||||
+checkbox("colouriseBrackets", "Colourise matching bracket pairs")
|
+checkbox("colouriseBrackets", "Colourise matching bracket pairs")
|
||||||
#compilation.tab-pane.form-group(role="group")
|
#compilation.tab-pane(role="group")
|
||||||
div
|
div
|
||||||
+checkbox("compileOnChange", "Compile automatically when source changes")
|
+checkbox("compileOnChange", "Compile automatically when source changes")
|
||||||
+checkbox("autoDelayBeforeCompile", "Use automatic delay before compiling")
|
+checkbox("autoDelayBeforeCompile", "Use automatic delay before compiling")
|
||||||
div
|
div
|
||||||
label Delay before compiling:
|
mb-3
|
||||||
|
label.form-label(for="settings-input-delay") Delay before compiling:
|
||||||
span.delay-current-value
|
span.delay-current-value
|
||||||
.slider-input
|
.slider-input(id="settings-input-delay")
|
||||||
b 0.25s
|
b 0.25s
|
||||||
input.delay(type="range")
|
input.delay(type="range")
|
||||||
b 3s
|
b 3s
|
||||||
@@ -112,4 +112,4 @@ mixin input(cls, type, text, style)
|
|||||||
+checkbox("executorCompileOnChange", "Compile executor automatically when arguments change")
|
+checkbox("executorCompileOnChange", "Compile executor automatically when arguments change")
|
||||||
+checkbox("shakeStatusIconOnWarnings", "Shake the status icon on argument warnings")
|
+checkbox("shakeStatusIconOnWarnings", "Shake the status icon on argument warnings")
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close
|
button.btn.btn-outline-primary(type="button" data-bs-dismiss="modal") Close
|
||||||
|
|||||||
@@ -3,26 +3,23 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Share
|
h5.modal-title Share
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
.container
|
.container
|
||||||
|
label.form-label.visually-hidden(for="share-permalink") Share URL
|
||||||
.input-group
|
.input-group
|
||||||
input.form-control.permalink(type="text" placeholder="Loading" readonly size="1024")
|
input.form-control.permalink#share-permalink(type="text" placeholder="Loading" readonly size="1024" aria-describedby="share-permalink-help")
|
||||||
.input-group-append
|
button.btn.btn-outline-secondary.clippy(type="button" data-clipboard-target="#sharelinkdialog .permalink" title="Copy to clipboard" aria-label="Copy to clipboard")
|
||||||
button.btn.btn-outline-secondary.clippy(type="button" data-clipboard-target="#sharelinkdialog .permalink" title="Copy to clipboard")
|
|
||||||
span.fa.fa-clipboard
|
span.fa.fa-clipboard
|
||||||
#embedsettings.form-group(role="group")
|
small.form-text.text-muted#share-permalink-help Use this URL to share your code with others
|
||||||
.checkbox
|
#embedsettings.mb-3(role="group")
|
||||||
label
|
.form-check
|
||||||
input.readOnly(type="checkbox")
|
input.form-check-input.readOnly(type="checkbox" id="share-checkbox-readonly")
|
||||||
| Read Only
|
label.form-check-label(for="share-checkbox-readonly") Read Only
|
||||||
.checkbox
|
.form-check
|
||||||
label
|
input.form-check-input.hideEditorToolbars(type="checkbox" id="share-checkbox-hideEditorToolbars")
|
||||||
input.hideEditorToolbars(type="checkbox")
|
label.form-check-label(for="share-checkbox-hideEditorToolbars") Hide Editor Toolbars
|
||||||
| Hide Editor Toolbars
|
|
||||||
if sharingEnabled
|
if sharingEnabled
|
||||||
.socialsharing.mt-2
|
.socialsharing.mt-2
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Load Site Template
|
h5.modal-title Load Site Template
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.container
|
.container
|
||||||
.row(id="site-template-modal-row")
|
.row(id="site-template-modal-row")
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Timing
|
h5.modal-title Timing
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
#chart
|
#chart
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close
|
button.btn.btn-outline-primary(type="button" data-bs-dismiss="modal") Close
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
.modal-content
|
.modal-content
|
||||||
.modal-header
|
.modal-header
|
||||||
h5.modal-title Well, do you or not?
|
h5.modal-title Well, do you or not?
|
||||||
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
|
button.btn-close(type="button" data-bs-dismiss="modal" aria-hidden="true" aria-label="Close")
|
||||||
span(aria-hidden="true")
|
|
||||||
| ×
|
|
||||||
.modal-body
|
.modal-body
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-link.no(type="button" data-dismiss="modal") No
|
button.btn.btn-link.no(type="button" data-bs-dismiss="modal") No
|
||||||
button.btn.btn-link.yes(type="button" data-dismiss="modal") Yes
|
button.btn.btn-link.yes(type="button" data-bs-dismiss="modal") Yes
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.btn-group.btn-group-sm(role="group")
|
.btn-group.btn-group-sm(role="group")
|
||||||
select.function-selector
|
select.function-selector
|
||||||
.btn-group.btn-group-sm(role="group" aria-label="CFG Export")
|
.btn-group.btn-group-sm(role="group" aria-label="CFG Export")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
||||||
span.fas.fa-arrow-down
|
span.fas.fa-arrow-down
|
||||||
span.hideable Export
|
span.hideable Export
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
||||||
include ../../font-size
|
include ../../font-size
|
||||||
.btn-group.btn-group-sm.options(role="group")
|
.btn-group.btn-group-sm.options(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="ClangIR Options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="ClangIR Options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
||||||
span.fas.fa-anchor
|
span.fas.fa-anchor
|
||||||
span.hideable Options
|
span.hideable Options
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ mixin newPaneButton(classId, text, title, label, icon)
|
|||||||
button.btn.btn-sm.btn-light.load-save(title="Load or save text" aria-label="Load or save text")
|
button.btn.btn-sm.btn-light.load-save(title="Load or save text" aria-label="Load or save text")
|
||||||
span.fa.fa-save
|
span.fa.fa-save
|
||||||
span.hideable Save/Load
|
span.hideable Save/Load
|
||||||
button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="new-editor-dropdown-btn")
|
button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="new-editor-dropdown-btn")
|
||||||
span.fa.fa-plus
|
span.fa.fa-plus
|
||||||
span.hideable Add new...
|
span.hideable Add new...
|
||||||
.dropdown-menu(data-cy="new-editor-pane-dropdown")
|
.dropdown-menu(data-cy="new-editor-pane-dropdown")
|
||||||
@@ -18,7 +18,7 @@ mixin newPaneButton(classId, text, title, label, icon)
|
|||||||
+newPaneButton("add-executor", "Execution Only", "Add a new executor for this source", "New executor", "fas fa-microchip")
|
+newPaneButton("add-executor", "Execution Only", "Add a new executor for this source", "New executor", "fas fa-microchip")
|
||||||
+newPaneButton("conformance", "Conformance View", "Add a new conformance view", "New conformance view", "fa fa-list")
|
+newPaneButton("conformance", "Conformance View", "Add a new conformance view", "New conformance view", "fa fa-list")
|
||||||
+newPaneButton("add-editor", "Source Editor", "Add a new source editor", "New source editor", "fa fa-code")
|
+newPaneButton("add-editor", "Source Editor", "Add a new source editor", "New source editor", "fa fa-code")
|
||||||
button#vim-flag.btn.btn-sm.btn-light(title="Toggle Vim Keybindings")
|
button.vim-flag.btn.btn-sm.btn-light(title="Toggle Vim Keybindings")
|
||||||
span.fab.fa-vimeo-v
|
span.fab.fa-vimeo-v
|
||||||
span.hideable Vim
|
span.hideable Vim
|
||||||
if thirdPartyIntegrationEnabled
|
if thirdPartyIntegrationEnabled
|
||||||
@@ -35,10 +35,10 @@ mixin newPaneButton(classId, text, title, label, icon)
|
|||||||
button.btn.btn-sm.btn-outline-info.ctrlSNothing(disabled=true style="display: none")
|
button.btn.btn-sm.btn-outline-info.ctrlSNothing(disabled=true style="display: none")
|
||||||
span.fas.fa-smile
|
span.fas.fa-smile
|
||||||
|
|
||||||
.btn-group.btn-group-sm.ml-auto(role="group" aria-label="Editor language")
|
.btn-group.btn-group-sm.ms-auto(role="group" aria-label="Editor language")
|
||||||
button.btn.btn-sm.language-info
|
button.btn.btn-sm.language-info
|
||||||
span.fas.fa-info
|
span.fas.fa-info
|
||||||
select.change-language(title="Change this editor's (and associated panels) language" placeholder="Language" disabled=embedded && readOnly)
|
select.change-language(title="Change this editor's (and associated panels) language" placeholder="Language" disabled=embedded && readOnly)
|
||||||
div.currentCursorPosition
|
div.currentCursorPosition
|
||||||
div#v-status
|
div.v-status
|
||||||
.monaco-placeholder
|
.monaco-placeholder
|
||||||
|
|||||||
@@ -10,4 +10,4 @@
|
|||||||
button.btn.btn-sm.btn-light.select-all(type="button" title="Select all lines")
|
button.btn.btn-sm.btn-light.select-all(type="button" title="Select all lines")
|
||||||
span.fa.fa-align-justify(style="border: 1px dotted white;border-radius: 0.125em;padding: 2px")
|
span.fa.fa-align-justify(style="border: 1px dotted white;border-radius: 0.125em;padding: 2px")
|
||||||
span.hideable Select all
|
span.hideable Select all
|
||||||
pre.content.output-content
|
pre.content.output-content(aria-live="polite" role="log" aria-label="Compiler output")
|
||||||
|
|||||||
@@ -6,35 +6,31 @@ mixin newPaneButton(classId, text, title, icon)
|
|||||||
#compiler
|
#compiler
|
||||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
||||||
.btn-group.btn-group-sm(role="group" aria-label="Compiler picker")
|
.btn-group.btn-group-sm(role="group" aria-label="Compiler picker")
|
||||||
.input-group
|
|
||||||
.input-group-prepend
|
|
||||||
.input-group
|
.input-group
|
||||||
select.compiler-picker
|
select.compiler-picker
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
||||||
span
|
span
|
||||||
i.fa-solid.fa-arrow-up-right-from-square
|
i.fa-solid.fa-arrow-up-right-from-square
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.prepend-options(data-trigger="click" style="cursor: pointer;" role="button" title="All compilation options")
|
button.btn.btn-sm.btn-light.input-group-text.prepend-options(data-trigger="click" style="cursor: pointer;" role="button" title="All compilation options")
|
||||||
span.status-icon
|
span.status-icon
|
||||||
input.options.form-control(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
input.options.form-control(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-label="Compiler options")
|
||||||
.input-group-append.populararguments(title="Popular arguments")
|
.populararguments(title="Popular arguments")
|
||||||
button.btn.btn-sm.btn-light.btn-outline-secondary.dropdown-toggle.dropdown-toggle-split.popular-arguments-btn(type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
button.btn.btn-sm.btn-light.btn-outline-secondary.dropdown-toggle.dropdown-toggle-split.popular-arguments-btn(type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.sr-only Popular arguments
|
span.visually-hidden Popular arguments
|
||||||
div.dropdown-menu.dropdown-menu-right
|
div.dropdown-menu.dropdown-menu-end
|
||||||
button.dropdown-item.btn.btn-light.btn-sm
|
button.dropdown-item.btn.btn-light.btn-sm
|
||||||
.argmenuitem
|
.argmenuitem
|
||||||
span.argtitle Detailed Compiler Flags
|
span.argtitle Detailed Compiler Flags
|
||||||
span.argdescription Open a new window to edit verbose compiler flags
|
span.argdescription Open a new window to edit verbose compiler flags
|
||||||
include ../../font-size
|
include ../../font-size
|
||||||
.btn-group.btn-group-sm.filters(role="group")
|
.btn-group.btn-group-sm.filters(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Compiler output options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Change how the compiler's output is generated")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Compiler output options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Change how the compiler's output is generated")
|
||||||
span.fas.fa-cog
|
span.fas.fa-cog
|
||||||
span.hideable Output...
|
span.hideable Output...
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
include ../../options-output
|
include ../../options-output
|
||||||
.btn-group.btn-group-sm.filters(role="group")
|
.btn-group.btn-group-sm.filters(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Compiler output filters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Change how the compiler output is filtered")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Compiler output filters" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Change how the compiler output is filtered")
|
||||||
span.fas.fa-filter
|
span.fas.fa-filter
|
||||||
span.hideable Filter...
|
span.hideable Filter...
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -48,10 +44,10 @@ mixin newPaneButton(classId, text, title, icon)
|
|||||||
span.fas.fa-wrench
|
span.fas.fa-wrench
|
||||||
span.dp-text.hideable Overrides
|
span.dp-text.hideable Overrides
|
||||||
.btn-group.btn-group-sm(role="group")
|
.btn-group.btn-group-sm(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle.add-pane(type="button" title="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add new element for this compiler" data-cy="new-compiler-dropdown-btn")
|
button.btn.btn-sm.btn-light.dropdown-toggle.add-pane(type="button" title="Add a new pane" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add new element for this compiler" data-cy="new-compiler-dropdown-btn")
|
||||||
span.fas.fa-plus
|
span.fas.fa-plus
|
||||||
span.hideable Add new...
|
span.hideable Add new...
|
||||||
.dropdown-menu.dropdown-menu-right.new-pane-dropdown(data-cy="new-compiler-pane-dropdown")
|
.dropdown-menu.dropdown-menu-end.new-pane-dropdown(data-cy="new-compiler-pane-dropdown")
|
||||||
+newPaneButton("add-compiler", "Clone Compiler", "Clone this compiler window (click or drag)", "far fa-clone")
|
+newPaneButton("add-compiler", "Clone Compiler", "Clone this compiler window (click or drag)", "far fa-clone")
|
||||||
+newPaneButton("create-executor", "Executor From This", "Create executor from this compiler", "fas fa-microchip")
|
+newPaneButton("create-executor", "Executor From This", "Create executor from this compiler", "fas fa-microchip")
|
||||||
+newPaneButton("view-optimization", "Opt Remarks", "Show optimization remarks", "fas fa-weight")
|
+newPaneButton("view-optimization", "Opt Remarks", "Show optimization remarks", "fas fa-weight")
|
||||||
@@ -73,22 +69,21 @@ mixin newPaneButton(classId, text, title, icon)
|
|||||||
+newPaneButton("view-gnatdebug", "GNAT Debug Expanded Code", "Show GNAT debug expanded code", "fas fa-tree")
|
+newPaneButton("view-gnatdebug", "GNAT Debug Expanded Code", "Show GNAT debug expanded code", "fas fa-tree")
|
||||||
+newPaneButton("view-cfg", "Control Flow Graph", "Show assembly control flow graphs", "fas fa-exchange-alt")
|
+newPaneButton("view-cfg", "Control Flow Graph", "Show assembly control flow graphs", "fas fa-exchange-alt")
|
||||||
.btn-group.btn-group-sm(role="group")
|
.btn-group.btn-group-sm(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle.add-tool(type="button" title="Add tool" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add tooling to this editor and compiler")
|
button.btn.btn-sm.btn-light.dropdown-toggle.add-tool(type="button" title="Add tool" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add tooling to this editor and compiler")
|
||||||
span.fas.fa-screwdriver
|
span.fas.fa-screwdriver
|
||||||
span.hideable Add tool...
|
span.hideable Add tool...
|
||||||
.dropdown-menu.dropdown-menu-right.new-tool-dropdown
|
.dropdown-menu.dropdown-menu-end.new-tool-dropdown
|
||||||
.monaco-placeholder
|
.monaco-placeholder
|
||||||
.bottom-bar.bg-light
|
.bottom-bar.bg-light
|
||||||
if !embedded
|
if !embedded
|
||||||
.btn-group.btn-group-sm
|
.btn-group.btn-group-sm
|
||||||
.input-group
|
.input-group
|
||||||
.input-group-prepend
|
button.btn.btn-sm.btn-light.clear-cache(title="Clear cache & recompile" aria-label="Clear cache and recompile")
|
||||||
button.btn.btn-sm.btn-light.clear-cache(title="Clear cache & recompile")
|
|
||||||
span.fas.fa-redo
|
span.fas.fa-redo
|
||||||
button.btn.btn-sm.btn-light.output-btn(data-cy="new-output-pane-btn")
|
button.btn.btn-sm.btn-light.output-btn(data-cy="new-output-pane-btn" aria-label="Show compiler output")
|
||||||
span.fas.fa-receipt.status-text
|
span.fas.fa-receipt.status-text
|
||||||
| Output
|
| Output
|
||||||
span.output-count
|
span.output-count(aria-live="polite")
|
||||||
| (
|
| (
|
||||||
span.text-count
|
span.text-count
|
||||||
| 0
|
| 0
|
||||||
@@ -96,11 +91,11 @@ mixin newPaneButton(classId, text, title, icon)
|
|||||||
span.err-count
|
span.err-count
|
||||||
| 0
|
| 0
|
||||||
| )
|
| )
|
||||||
span.short-compiler-name.mr-1
|
span.short-compiler-name.me-1(aria-hidden="true")
|
||||||
button.btn.btn-sm.btn-light.full-compiler-name(data-trigger="click" style="cursor: pointer;" role="button")
|
button.btn.btn-sm.btn-light.full-compiler-name(data-trigger="click" style="cursor: pointer;" role="button" aria-label="Show compiler information")
|
||||||
span.fas.fa-info
|
span.fas.fa-info
|
||||||
span.compile-info.mr-1(title="Compilation info")
|
span.compile-info.me-1(title="Compilation info" aria-label="Compilation information")
|
||||||
button.btn.btn-sm.btn-light.full-timing-info(data-trigger="click" style="cursor: pointer;" role="button")
|
button.btn.btn-sm.btn-light.full-timing-info(data-trigger="click" style="cursor: pointer;" role="button" aria-label="Show full timing information")
|
||||||
span.fas.fa-chart-bar
|
span.fas.fa-chart-bar
|
||||||
button.btn.btn-sm.btn-light.compiler-license(data-trigger="click" style="cursor: pointer;" role="button")
|
button.btn.btn-sm.btn-light.compiler-license(data-trigger="click" style="cursor: pointer;" role="button" aria-label="View compiler license")
|
||||||
span Compiler License
|
span Compiler License
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
||||||
include ../../font-size
|
include ../../font-size
|
||||||
.btn-group.btn-group-sm(role="group")
|
.btn-group.btn-group-sm(role="group")
|
||||||
select.change-device(placeholder="Select a device...")
|
select.form-select.change-device(placeholder="Select a device...")
|
||||||
.monaco-placeholder
|
.monaco-placeholder
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
#diff
|
#diff
|
||||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.py-1.d-flex.align-items-center(role="toolbar")
|
||||||
include ../../font-size
|
include ../../font-size
|
||||||
.btn-group.btn-group-sm
|
.btn-group.btn-group-sm.flex-grow-1.me-2
|
||||||
.input-group.input-group-sm.mb-auto
|
.input-group.input-group-sm.w-100
|
||||||
.input-group-prepend
|
|
||||||
label.input-group-text
|
label.input-group-text
|
||||||
| Left:
|
| Left:
|
||||||
select.diff-picker.lhs(placeholder="Select compiler...")
|
select.diff-picker.lhs(placeholder="Select compiler...")
|
||||||
select.difftype-picker.lhsdifftype(placeholder="...")
|
select.difftype-picker.lhsdifftype(placeholder="...")
|
||||||
.btn-group.btn-group-sm.ml-4
|
.btn-group.btn-group-sm.flex-grow-1
|
||||||
.input-group.input-group-sm.mb-auto
|
.input-group.input-group-sm.w-100
|
||||||
.input-group-prepend
|
|
||||||
label.input-group-text
|
label.input-group-text
|
||||||
| Right:
|
| Right:
|
||||||
select.diff-picker.rhs(placeholder="Select compiler...")
|
select.diff-picker.rhs(placeholder="Select compiler...")
|
||||||
|
|||||||
@@ -29,41 +29,38 @@
|
|||||||
span.hideable Compiler output
|
span.hideable Compiler output
|
||||||
.top-bar.btn-toolbar.bg-light.panel-compilation(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.panel-compilation(role="toolbar")
|
||||||
.btn-group.btn-group-sm(role="group" aria-label="Compiler picker")
|
.btn-group.btn-group-sm(role="group" aria-label="Compiler picker")
|
||||||
.input-group
|
|
||||||
.input-group-prepend
|
|
||||||
.input-group
|
.input-group
|
||||||
select.compiler-picker
|
select.compiler-picker
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
||||||
span
|
span
|
||||||
i.fa-solid.fa-arrow-up-right-from-square
|
i.fa-solid.fa-arrow-up-right-from-square
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.prepend-options(data-trigger="click" style="cursor: pointer;" role="button" title="All compilation options")
|
button.btn.btn-sm.btn-light.input-group-text.prepend-options(data-trigger="click" style="cursor: pointer;" role="button" title="All compilation options")
|
||||||
span.btn.btn-sm.btn-light.status-icon
|
span.btn.btn-sm.btn-light.status-icon
|
||||||
input.compilation-options.form-control(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
label.visually-hidden(for="compilation-options") Compiler options for execution
|
||||||
|
input.compilation-options.form-control#compilation-options(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-label="Compiler options for execution")
|
||||||
// TODO: Maybe enable this in the future?
|
// TODO: Maybe enable this in the future?
|
||||||
//.input-group-append.populararguments(title="Popular arguments")
|
//.populararguments(title="Popular arguments")
|
||||||
button.btn.btn-sm.btn-light.btn-outline-secondary.dropdown-toggle.dropdown-toggle-split.popular-arguments-btn(type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
button.btn.btn-sm.btn-light.btn-outline-secondary.dropdown-toggle.dropdown-toggle-split.popular-arguments-btn(type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.sr-only Popular arguments
|
span.visually-hidden Popular arguments
|
||||||
div.dropdown-menu.dropdown-menu-right
|
div.dropdown-menu.dropdown-menu-end
|
||||||
button.dropdown-item.btn.btn-light.btn-sm
|
button.dropdown-item.btn.btn-light.btn-sm
|
||||||
.argmenuitem
|
.argmenuitem
|
||||||
span.argtitle Detailed Compiler Flags
|
span.argtitle Detailed Compiler Flags
|
||||||
span.argdescription Open a new window to edit verbose compiler flags
|
span.argdescription Open a new window to edit verbose compiler flags
|
||||||
.top-bar.btn-toolbar.bg-light.panel-args.d-none(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.panel-args.d-none(role="toolbar")
|
||||||
input.execution-arguments.form-control(type="text" placeholder="Execution arguments..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
input.execution-arguments.form-control(type="text" placeholder="Execution arguments..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-label="Execution arguments")
|
||||||
.top-bar.btn-toolbar.bg-light.panel-stdin.d-none(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.panel-stdin.d-none(role="toolbar")
|
||||||
textarea.execution-stdin.form-control(placeholder="Execution stdin..." cols="1024" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-multiline="false" style="resize: vertical")
|
textarea.execution-stdin.form-control(placeholder="Execution stdin..." cols="1024" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" aria-multiline="true" style="resize: vertical" aria-label="Standard input for program execution")
|
||||||
pre.content
|
pre.content
|
||||||
.execution-status
|
.execution-status(aria-live="polite" role="status" aria-label="Execution status")
|
||||||
.compiler-output
|
.compiler-output(aria-live="polite" role="log" aria-label="Compiler output")
|
||||||
.execution-output
|
.execution-output(aria-live="polite" role="log" aria-label="Program execution output")
|
||||||
.bottom-bar.bg-light
|
.bottom-bar.bg-light
|
||||||
button.btn.btn-sm.btn-light.rerun(title="Rerun")
|
button.btn.btn-sm.btn-light.rerun(title="Rerun" aria-label="Rerun execution")
|
||||||
span.fas.fa-circle-play
|
span.fas.fa-circle-play
|
||||||
button.btn.btn-sm.btn-light.clear-cache(title="Clear cache & recompile")
|
button.btn.btn-sm.btn-light.clear-cache(title="Clear cache & recompile" aria-label="Clear cache and recompile")
|
||||||
span.fas.fa-redo
|
span.fas.fa-redo
|
||||||
span.short-compiler-name
|
span.short-compiler-name(aria-hidden="true")
|
||||||
button.btn.btn-sm.btn-light.fas.fa-info.full-compiler-name(data-trigger="click" style="cursor: pointer;" role="button")
|
button.btn.btn-sm.btn-light.fas.fa-info.full-compiler-name(data-trigger="click" style="cursor: pointer;" role="button" aria-label="Show compiler info")
|
||||||
span.compile-time(title="Compilation time (Result size)")
|
span.compile-time(title="Compilation time (Result size)" aria-label="Compilation time and result size")
|
||||||
button.btn.btn-sm.btn-light.fas.fa-chart-bar.full-timing-info(data-trigger="click" style="cursor: pointer;" role="button")
|
button.btn.btn-sm.btn-light.fas.fa-chart-bar.full-timing-info(data-trigger="click" style="cursor: pointer;" role="button" aria-label="Show full timing information")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
.btn-group.btn-group-sm(role="group")
|
.btn-group.btn-group-sm(role="group")
|
||||||
select.gccdump-pass-picker(placeholder="Select a pass...")
|
select.gccdump-pass-picker(placeholder="Select a pass...")
|
||||||
.btn-group.btn-group-sm.dump-filters
|
.btn-group.btn-group-sm.dump-filters
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Dump passes" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Available dump passes")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Dump passes" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Available dump passes")
|
||||||
span.fas.fa-compass
|
span.fas.fa-compass
|
||||||
span.hideable Passes
|
span.hideable Passes
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -18,7 +18,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
+optionButton("rtlDump", true, "RTL Pass", "Show RTL passes")
|
+optionButton("rtlDump", true, "RTL Pass", "Show RTL passes")
|
||||||
+optionButton("ipaDump", true, "IPA Pass", "Show IPA passes")
|
+optionButton("ipaDump", true, "IPA Pass", "Show IPA passes")
|
||||||
.btn-group.btn-group-sm.dump-filters
|
.btn-group.btn-group-sm.dump-filters
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Dump pass options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Control the details of the dump")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Dump pass options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Control the details of the dump")
|
||||||
span.fas.fa-microchip
|
span.fas.fa-microchip
|
||||||
span.hideable Options
|
span.hideable Options
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
span Wrap lines
|
span Wrap lines
|
||||||
input.d-none(type="checkbox" checked=false)
|
input.d-none(type="checkbox" checked=false)
|
||||||
.btn-group.btn-group-sm.options(role="group")
|
.btn-group.btn-group-sm.options(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
||||||
span.fas.fa-anchor
|
span.fas.fa-anchor
|
||||||
span.hideable Options
|
span.hideable Options
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
+optionButton("demangle-symbols", true, "Demangle Symbols", "Demangle symbols")
|
+optionButton("demangle-symbols", true, "Demangle Symbols", "Demangle symbols")
|
||||||
+optionButton("-fno-discard-value-names", true, "-fno-discard-value-names", "Keep value names instead of LLVM value numbers")
|
+optionButton("-fno-discard-value-names", true, "-fno-discard-value-names", "Keep value names instead of LLVM value numbers")
|
||||||
.btn-group.btn-group-sm.filters(role="group")
|
.btn-group.btn-group-sm.filters(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Filters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Filters" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
||||||
span.fas.fa-filter
|
span.fas.fa-filter
|
||||||
span.hideable Filters
|
span.hideable Filters
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
||||||
include ../../font-size
|
include ../../font-size
|
||||||
.btn-group.btn-group-sm.options(role="group")
|
.btn-group.btn-group-sm.options(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt Pass Options" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt Pass Options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
||||||
span.fas.fa-anchor
|
span.fas.fa-anchor
|
||||||
span.hideable Options
|
span.hideable Options
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -16,7 +16,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
+optionButton("demangle-symbols", true, "Demangle Symbols", "Demangle symbols")
|
+optionButton("demangle-symbols", true, "Demangle Symbols", "Demangle symbols")
|
||||||
+optionButton("-fno-discard-value-names", true, "-fno-discard-value-names", "Keep value names instead of LLVM value numbers")
|
+optionButton("-fno-discard-value-names", true, "-fno-discard-value-names", "Keep value names instead of LLVM value numbers")
|
||||||
.btn-group.btn-group-sm.filters(role="group")
|
.btn-group.btn-group-sm.filters(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt Pass Filters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt Pass Filters" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
||||||
span.fas.fa-filter
|
span.fas.fa-filter
|
||||||
span.hideable Filters
|
span.hideable Filters
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -26,7 +26,6 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
//- +optionButton("library-functions", true, "Filter Library Functions", "Filter library functions")
|
//- +optionButton("library-functions", true, "Filter Library Functions", "Filter library functions")
|
||||||
.btn-group.btn-group-sm
|
.btn-group.btn-group-sm
|
||||||
.input-group.input-group-sm.mb-auto
|
.input-group.input-group-sm.mb-auto
|
||||||
.input-group-prepend
|
|
||||||
label.input-group-text.opt-group-name
|
label.input-group-text.opt-group-name
|
||||||
| Function:
|
| Function:
|
||||||
select.opt-group-picker.group-selector(placeholder="Select group")
|
select.opt-group-picker.group-selector(placeholder="Select group")
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ mixin optionButton(bind, isActive, text, title)
|
|||||||
input.d-none(type="checkbox" checked=false)
|
input.d-none(type="checkbox" checked=false)
|
||||||
// TODO: Options - display inlining context, color token (from col-num), remove duplicates
|
// TODO: Options - display inlining context, color token (from col-num), remove duplicates
|
||||||
.btn-group.btn-group-sm.filters(role="group")
|
.btn-group.btn-group-sm.filters(role="group")
|
||||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt-Remarks Filters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Opt-Remarks Filters" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output filters")
|
||||||
span.fas.fa-filter
|
span.fas.fa-filter
|
||||||
span.hideable Filters
|
span.hideable Filters
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#tree
|
#tree
|
||||||
.top-bar.btn-toolbar.bg-light.mainbar(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.mainbar(role="toolbar")
|
||||||
.btn-group.btn-group-sm.menu(role="group" aria-label="Menu")
|
.btn-group.btn-group-sm.menu(role="group" aria-label="Menu")
|
||||||
button.dropdown-toggle.btn.btn-sm.btn-light.file-menu(type="button" title="File" aria-label="File" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
button.dropdown-toggle.btn.btn-sm.btn-light.file-menu(type="button" title="File" aria-label="File" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.fa.fa-save
|
span.fa.fa-save
|
||||||
span.hideable Project
|
span.hideable Project
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
span.dropdown-icon.fa.fa-save
|
span.dropdown-icon.fa.fa-save
|
||||||
| Save
|
| Save
|
||||||
.btn-group.btn-group-sm.options(role="group" aria-label="Tree settings")
|
.btn-group.btn-group-sm.options(role="group" aria-label="Tree settings")
|
||||||
button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false")
|
||||||
span.fa.fa-plus
|
span.fa.fa-plus
|
||||||
span.hideable Add new...
|
span.hideable Add new...
|
||||||
.dropdown-menu
|
.dropdown-menu
|
||||||
@@ -27,19 +27,19 @@
|
|||||||
button.btn.btn-sm.btn-light.cmake-project(type="button" title="CMake project" data-bind="isCMakeProject" aria-pressed="false" aria-label="CMake project")
|
button.btn.btn-sm.btn-light.cmake-project(type="button" title="CMake project" data-bind="isCMakeProject" aria-pressed="false" aria-label="CMake project")
|
||||||
span CMake
|
span CMake
|
||||||
input.d-none(type="checkbox" checked=false)
|
input.d-none(type="checkbox" checked=false)
|
||||||
.btn-group.btn-group-sm.ml-auto(role="group" aria-label="Language")
|
.btn-group.btn-group-sm.ms-auto(role="group" aria-label="Language")
|
||||||
select.change-language(title="Change the language" placeholder="Language" disabled=embedded && readOnly)
|
select.change-language(title="Change the language" placeholder="Language" disabled=embedded && readOnly)
|
||||||
.top-bar.btn-toolbar.bg-light.panel-args.d-none(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.panel-args.d-none(role="toolbar")
|
||||||
input.cmake-arguments.form-control(type="text" placeholder="CMake arguments..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
input.cmake-arguments.form-control(type="text" placeholder="CMake arguments..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
||||||
.top-bar.btn-toolbar.bg-light.panel-outputfile.d-none(role="toolbar")
|
.top-bar.btn-toolbar.bg-light.panel-outputfile.d-none(role="toolbar")
|
||||||
input.cmake-customOutputFilename.form-control(type="text" placeholder="output.s" size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
input.cmake-customOutputFilename.form-control(type="text" placeholder="output.s" size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
||||||
.tree.v-scroll
|
.tree.v-scroll
|
||||||
ul.list-group
|
ul.list-group.list-group-flush
|
||||||
li.root.list-group-item.far-fa-folder
|
li.root.list-group-item.far-fa-folder
|
||||||
.group-header Included files
|
.group-header Included files
|
||||||
ul.list-group.named-editors
|
ul.list-group.list-group-flush.named-editors
|
||||||
li.root.list-group-item.far-fa-folder
|
li.root.list-group-item.far-fa-folder
|
||||||
.group-header Excluded files
|
.group-header Excluded files
|
||||||
ul.list-group.unnamed-editors
|
ul.list-group.list-group-flush.unnamed-editors
|
||||||
li.drophere.row.align-items-center(style="display: none;")
|
li.drophere.row.align-items-center(style="display: none;")
|
||||||
span.col-lg.text-center Drop files here
|
span.col-lg.text-center Drop files here
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
#compiler-selector
|
#compiler-selector
|
||||||
.form-row
|
.row
|
||||||
.input-group
|
|
||||||
.input-group-prepend
|
|
||||||
.input-group
|
.input-group
|
||||||
select.compiler-picker
|
select.compiler-picker
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
button.btn.btn-sm.btn-light.input-group-text.picker-popout-button(data-trigger="click" style="cursor: pointer;" role="button" title="Compiler picker popout")
|
||||||
span
|
span
|
||||||
i.fa-solid.fa-arrow-up-right-from-square
|
i.fa-solid.fa-arrow-up-right-from-square
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.btn-light.input-group-text.prepend-options(tabindex="0" data-trigger="focus" style="cursor: pointer;" role="button" title="All compilation options")
|
button.btn.btn-sm.btn-light.input-group-text.prepend-options(tabindex="0" data-trigger="focus" style="cursor: pointer;" role="button" title="All compilation options")
|
||||||
span.btn.btn-sm.btn-light.status-icon
|
span.btn.btn-sm.btn-light.status-icon
|
||||||
input.conformance-options.form-control(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
input.conformance-options.form-control(type="text" placeholder="Compiler options..." size="256" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false")
|
||||||
.input-group-append
|
|
||||||
button.btn.btn-sm.fas.fa-receipt.d-none.compiler-out.compiler-selector-icon(disabled=true style="cursor: help;" title="This compiler has generated some output. Open its associated pane to read it.")
|
button.btn.btn-sm.fas.fa-receipt.d-none.compiler-out.compiler-selector-icon(disabled=true style="cursor: help;" title="This compiler has generated some output. Open its associated pane to read it.")
|
||||||
button.btn.btn-sm.fas.fa-times.close.compiler-selector-icon(aria-label="Close" title="Close")
|
button.btn.btn-sm.fas.fa-times.close-compiler.compiler-selector-icon(aria-label="Close" title="Close")
|
||||||
button.btn.btn-sm.fas.fa-share.close.extract-compiler.compiler-selector-icon(aria-label="Pop compiler" title="Show compiler")
|
button.btn.btn-sm.fas.fa-share.extract-compiler.compiler-selector-icon(aria-label="Pop compiler" title="Show compiler")
|
||||||
button.btn.btn-sm.fas.fa-copy.close.copy-compiler.compiler-selector-icon(aria-label="Copy compiler" title="Copy compiler")
|
button.btn.btn-sm.fas.fa-copy.copy-compiler.compiler-selector-icon(aria-label="Copy compiler" title="Copy compiler")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
span
|
span
|
||||||
b.lib-name
|
b.lib-name
|
||||||
span.lib-version
|
span.lib-version
|
||||||
select.custom-select.custom-select-sm.lib-version-select
|
select.form-select.form-select-sm.lib-version-select
|
||||||
option -
|
option -
|
||||||
.card-body
|
.card-body
|
||||||
p.lib-description
|
p.lib-description
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#libs-entry
|
#libs-entry
|
||||||
.input-group.input-group-sm
|
.input-group.input-group-sm
|
||||||
.input-group-prepend
|
|
||||||
label.input-group-text
|
label.input-group-text
|
||||||
select.custom-select.custom-select-sm
|
select.form-select.form-select-sm
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.card-header
|
.card-header
|
||||||
span.override-name
|
span.override-name
|
||||||
span.override
|
span.override
|
||||||
select.custom-select.custom-select-sm
|
select.form-select.form-select-sm
|
||||||
.card-body
|
.card-body
|
||||||
p.override-description
|
p.override-description
|
||||||
span.override-fav
|
span.override-fav
|
||||||
|
|||||||
@@ -13,4 +13,4 @@
|
|||||||
.runtime-tool-option
|
.runtime-tool-option
|
||||||
span.tool-option-name
|
span.tool-option-name
|
||||||
span.tool-option-select
|
span.tool-option-select
|
||||||
select.tool-option-select.custom-select-sm
|
select.tool-option-select.form-select-sm
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#tree-editor-tpl
|
#tree-editor-tpl
|
||||||
li.list-group-item.tree-editor-file.input-group-append
|
li.list-group-item.tree-editor-file
|
||||||
span.filename someresource.txt
|
span.filename someresource.txt
|
||||||
button.btn.delete-file.fa.fa-trash(title="Remove this file" aria-label="Delete")
|
button.btn.delete-file.fa.fa-trash(title="Remove this file" aria-label="Delete")
|
||||||
button.btn.rename-file.fa.fa-tag(title="Rename this file" aria-label="Rename")
|
button.btn.rename-file.fa.fa-tag(title="Rename this file" aria-label="Rename")
|
||||||
|
|||||||
Reference in New Issue
Block a user