no issue
- Glimmer components do not have a `.element` property so we need to set it manually because the editor currently reaches into card components to calculate the element's rect for selection when creating snippets
refs https://github.com/TryGhost/Team/issues/992
- added "Link to this post" option that uses the preview URL as it's currently the only guaranteed URL that we know before a post is published
- added "Free email signup" option
- added "Paid subscription" and "Upgrade or change plan" options that are only shown when Stripe is connected
refs https://github.com/TryGhost/Team/issues/992
- within cards we sometimes want access to the `post` record so that UI or copy can be changed based on what is currently being edited
- added ability to pass `@cardOptions` through to the editor components
- fixed KoenigEditor not correctly assigning the `cardOptions` object to the `options` object that gets passed to every card when they are rendered
refs https://github.com/TryGhost/Team/issues/973
- added `@showCreate` option to `<GhInputWithSelect>` that enables the create option without having to pass a function in `@showCreateWhen`
- fixed autofocus not focusing input element in `<GhInputWithSelect>` when `autofocus="true"` isn't enough by itself
- updated `selectOrCreate` in `<GhInputWithSelect>` to trigger `onChange` if it's passed in rather than `onInput`
- swapped input in labs snippet input to `<GhInputWithSelect>`
- added actions for updating a snippet when an existing snippet is selected
- added action to editor control for saving an updated snippet
refs https://github.com/TryGhost/Team/issues/992
- swapped input element for `<GhInputWithSelect>`
- added `config.getSiteUrl()` method for generating front-end URLs including subdomain
- added example suggested URLs to email-cta card to pass as options to button url input
Refs https://github.com/TryGhost/Team/issues/928
- Added icons for top and bottom border
- Updated spacing for hr element when not in edit mode
- Got rid of hr element when in edit mode
- Got rid of left border for email, html and markdown cards and feature image
refs https://github.com/TryGhost/Team/issues/928
- added btn group for selecting left/center alignment of CTA button
- updated rendered view to center the button when center alignment is selected
refs https://github.com/TryGhost/Team/issues/928
- two toggle buttons is cleaner than 4 buttons to achieve the same thing
- adjusted payload to have `dividerTop` and `dividerBottom` attributes rather
refs https://github.com/TryGhost/Team/issues/928
- adds 4 buttons to email-cta toolbar for changing border setting to `none`, `top`, `bottom`, and `both`
- output `<hr>` elements at top and bottom of email-cta card contents when set
- fixed clicks on non-edit-mode toolbar items switching cards into edit mode
refs https://github.com/TryGhost/Team/issues/928
- it's possible to set a button with no content in the CTA card but the auto-removal when exiting edit mode was only checking for presence of content
- updated to only remove the card when no content, button text, or button url has been set
refs https://github.com/TryGhost/Team/issues/927
- button should be visible when not editing if both text and url are set
- added container for the content section so other links aren't clickable
- added tooltip to button so button url can be checked without having to go into edit mode
refs https://github.com/TryGhost/Team/issues/927
- added CTA `button and url inputs to email-cta card
- added `textColorForBackgroundColor` color util and used it to add a white/black text color variable that can be used when the accent color is used as a background color
- added `{{hex-adjust}}` helper for modifying lightness and saturation of a hex color
- adjusted inline power-select dropdown styling
refs https://github.com/TryGhost/Team/issues/927
- allows for more information about a card to be shown when hovering over the indicator to the left of the card's section in the editor
refs https://github.com/TryGhost/Team/issues/931
- prototype button has served it's purpose in answering questions and is no longer being used
- groundwork is left in place for future component-based atoms
refs https://github.com/TryGhost/Team/issues/931
- adds handling for component atoms
- add prototype button atom to test atom behaviour
- add `Cmd+Shift+B` keyboard shortcut to create a dummy button atom when the `emailCardSegments` feature is enabled
refs https://github.com/TryGhost/Team/issues/926
- updated `<KoenigEditor>` so it creates default card payloads as TrackedObject instances so that getters in glimmer component based cards can track changes to payload properties
- added dropdown free/paid selector to email-cta card that sets the `segment` payload property to the respective filter
- updated design to show the footer outside of edit mode too so that the selected segment is always visible
no issue
- switched to native class syntax
- updated to glimmer/octane syntax
- fixed infinite render issue from `<KoenigTextReplacementHtmlInput>`'s `didReceiveAttrs()` lifecycle hook
refs https://github.com/TryGhost/Team/issues/910
- readying the foundation for adding segment selection and CTA config to the `email-cta` card
- will only be available to select from card menus when the `emailCardSegments` feature flag is enabled
refs https://github.com/TryGhost/Team/issues/910
- added `card-is-available` helper that handles the previous `card.developerExperiment` and the new `card.feature` options
- updated `<KoenigMenuContent>` to use the `card-is-available` helper in the conditional when adding cards to the list
Cards can be gated by feature when specifying them in `cards.js`, in the card definition object you can add `feature: 'flagName'` which will mean the card is only available when that feature is enabled.
closes https://github.com/TryGhost/Team/issues/749
- resize event listener is created twice when converting a link to an embed card, if we don't clear the older resize event handler before creating a new one then it persists after the component is torn down and the iframe no longer exists
no issue
- Grammarly have indicated their extension is now compatible with the underlying editor technology used in Ghost
- removed html attributes that explicitly disabled the extension on our editor fields
no issue
- sometimes it was possible for a drop target element to not have a child which would cause an error and cause drag/drop to get stuck with the dragged element sticking to the cursor with no action occurring on mouseup, requiring an `Esc` press but all further drags also being broken
- added a guard so we can handle `element.firstChild` not existing
refs https://github.com/TryGhost/Team/issues/465
- modifies `<KoenigLinkInput>` to add a "direct" mode that is not tied to editor selection
- adds link toolbar icon to image card toolbar
- adds link editing mode to image card that replaces toolbar with link input
- stores url in `href` attribute in card payload
refs https://github.com/TryGhost/Ghost/issues/12646
- ensures new content is created with the 4.0 ghost version so the renderer will use latest output
- re-applies ghost version to mobiledoc each time we get a newly serialized mobiledoc document from mobiledoc-kit because mobiledoc-kit is not aware of our custom properties and won't pass them through the deserialise->serialise process
closes https://github.com/TryGhost/Ghost/issues/12459
- Email design settings don't open in some cases when footer html is set as null, specifically on import
- Patches html cleanup to use empty string in case of null footer value
no issue
- email cards a block cards so have a distinct edit mode, that type of card should always have an edit icon in the toolbar for consistency and ease of use when the double-click or cmd+enter shortcuts aren't known
no issue
The toolbar display/positioning logic was recently changed so that the toolbar is shown when a `saveAsSnippet` action is passed in. However the `_setToolbarProperties` method wasn't taking into account the toolbar element not being present when in editing mode such as when a block-editable card (markdown, html, code) is created.
- remove conditional logic that may change over time and replace it with checks for the toolbar element existing
no issue
- extracted item matching into a separate function
- modified item matching to work with arrays (existing exact match behaviour) or functions which can be defined per-item
- changed snippet item `matches` to a function that does a naive match or the typed query to any part of the snippet's title
no issue
Snippets are pieces of saved content that are given a name and made available for easy and quick insertion when editing posts or pages. They can contain rich text, cards, or a combination of both making it faster and less error-prone to re-use pieces of content across multiple posts. Snippet length is not constrained meaning they can also stand in as post type templates alleviating the need to keep drafts around as templates and copy/pasting each time they are used.
Feature changes:
- added "create snippet" icon to selection and card toolbars
- added "Snippets" section to the plus and slash menus
- for the slash menu, continuing to type after opening the menu will filter by snippet name
- all saved snippets are available to all staff users
- snippets can be deleted by clicking the trash can icon when hovering the mouse over a snippet entry in the plus or slash menus
- creation/deletion of snippets is available to staff users with the owner, admin, or editor role
This commit:
- removed developer experiments guard around snippet UI
no issue
- snippets can only be created and deleted by owners/admins/editors
- added a property in the editor controller to determine if the logged in user has sufficient permissions, then only pass the appropriate save/delete snippet actions to the editor component if the check is passed
- updates koenig menus and toolbars to skip rendering of buttons if the associated action function is not available
no issue
- when deleting a snippet we display a confirmation modal, if the background is clicked to dismiss the modal then the menus closed too which is a different behaviour to clicking the close/cancel button inside the dialog
- adjusted the "ignore click" selector in the menus to include all fullscreen modal elements
no issue
- show a delete icon when a snippet is hovered in plus/slash menus
- show a confirmation dialog when the delete icon is clicked
- keep menus open whilst displaying the delete confirmation dialog
no issue
- it doesn't make sense to create snippets of bookmark/embed cards before they contain any content so we avoid passing the save snippet function through until content exists and the card has left it's input state
no issue
- with the addition of snippets the card menu contents height and potential label width are both growing considerably making the grid layout unworkable
no issue
- show the toolbar icon for any `<KoenigCard>` instance that has the `saveAsSnippet` action passed to it
- currently that's all cards except the HR card because that's a primitive element rather than containing any user-defined content
- add `koenigUi.inputHasFocus` so that card toolbars can be hidden when the snippet input is displayed
no issue
- all of our models which allow users to name something use `name` as the field descriptor rather than `title` so `snippet.title` was renamed for consistency
- also fixes typo in the plus-menu component that stopped clicking on snippets from working
closes https://github.com/TryGhost/Team/issues/411
- adds "Create snippet" icon to the editor toolbar
- uses the same link input component design for specifying snippet titles
- snippets are loaded in the background when the editor is accessed
- snippets are listed at the bottom of the card menus of the + and / menus
- clicking a snippet inserts the snippet's contents in place of the current blank section
no issue
- fixed all `no-shadow` linter warnings
- changed `no-shadow` eslint rule from `warn` to `error` so we don't re-introduce shadowed variables in the future
no issue
- now that we no longer have the `ember-sticky-element` dependency we're free to upgrade `ember-in-viewport`
- remove package.json resolution so latest version gets installed
- remove ember-in-viewport from renovate ignore config
- update `<GhScrollTrigger>` to match latest `ember-in-viewport` usage and convert to a glimmer component
- ensure `scrollableArea` is always set so that the trigger doesn't stop working after the first trigger
no issue
- native `position: sticky` support is now good enough across the board of our supported browser versions to use in place of a JS version for our use cases
- `ember-sticky-element` is preventing the dependency update of `ember-in-viewport` so removing it will allow a lot of our sub-dependencies to be updated
closes https://github.com/TryGhost/Ghost/issues/12110
- adds `{{gh-pluralize}}` helper that wraps the `{{pluralize}}` helper from `ember-inflector` but formats the number using our `{{format-number}}` helper
- updates all uses of `{{pluralize}}` to `{{gh-pluralize}}`
no issue
- Ember 3.20.0 introduced `{{in-element}}` as a public API in place of the now-deprecated `{{-in-element}}` private API
- replaced our usage of the private API with the public API
no issue
- extract width/height from selected local image when uploading and store in the payload with `src` once upload finishes
- capture width/height from Unsplash and store in the payload after selecting an image
refs #11863
* 🐛 Gave various buttons accessible labels
Hidden span elements are not rendered to assistive technologies, so duplicate the text in an aria-label on the button element.
* 🐛 Fixed various accessibility issues in the editor
* Made menus menus and menu item menuitems.
* Added labels to buttons where there were only hidden spans, or no text at all.
* Made separators show up for screen readers.
no issue
Keeps component JS backing files and template files in the same directory which avoids hunting across directories when working with components. Also lets you see all components when looking at one directory, whereas previously template-only or js-only components may not have been obvious without looking at both directories.
- ran [codemod](https://github.com/ember-codemods/ember-component-template-colocation-migrator/) for app-level components
- manually moved in-repo-addon component templates in `lib/koenig-editor`
- removed all explicit `layout` imports as JS/template associations are now made at build-time removing the need for them
- updated `.embercli` to default to new flat component structure
no issue
- we're adjusting the oembed endpoint to fetch larger thumbnails if possible and that results in Vimeo embed iframes being larger than the editor width which created large blank spaces above/below the video due to the iframe height not adjusting correctly
- in the embed card's resize routine, if we look for an embedded iframe and find a width/height attribute then we can use the aspect ratio to assign the correct height for the outer and inner iframes
refs https://github.com/TryGhost/Ghost/issues/11756
- we'd like to render fallbacks for embed cards in constrained environments such as emails where the `html` contents may not be suitable
- oembed gives us data to be able to create fallbacks this such as a `thumbnail_url`, author information, and sizing but we were not storing it
- this change removes the `html` and `type` data from the response object as the existing top-level payload properties then stores the remainder of the response under a `metadata` property
no issue
- show help at bottom of email card in edit mode with text explaining that the email card will only be included in emails
- set default content of the email card that includes the `{first_name}` replacement string
- changed behaviour to place cursor at end of the card contents when entering edit mode
no issue
- we don't want to allow text replacement strings to be split in half by html tags so we disallow any formats to be applied to them
- in the `<KoenigTextReplacementHtmlInput>`'s mobiledoc editor's `didUpdatePost` hook handler we loop over all markers in the post and if they have a code markup (we use this to represent replacement strings) then we strip any other markups
no issue
- `<code>` formatting is internal to the text replacement html input and shouldn't be persisted in the payload html
- adjust `cleanTextReplacementHtml` to strip out all `<code>` tags
- adjust `<CleanTextReplacementHtmlInput>` to strip `<code>` formatting when outputting html via the `onChange` action and to also put the `<code>` formatting back when receiving html
- adjust `<KoenigEmailCard>` to add the `<code>` formatting back around any replacement strings so that they are visible in the editor
no issue
- we want to keep the `{` and `}` chars when applying/removing formatting from text replacement strings so that you can see the full string with formatting
- added ability to specify a non-replaced special format which is used by the <kbd>Backspace</kbd> handler
- added helper utility to the text expansions for applying formatting to a match without replacing the "markdown" characters
no issue
- if the character used to define a special markup is different such as in the text replacement editor, pressing Backspace was not inserting the correct characters
refs 6f5c2a9557
- we previously set a fixed mobiledoc spec version in blank documents but when the editor was serializing to a json string after editing it was bumping the spec version
- makes the specific version a constant to be used when serializing any mobiledoc
no issue
- adds "Email" card to the card menus when developer experiments is turned on
- adds `<KoenigTextReplacementHtmlInput>` implementing most of Koenig except:
- uses html as it's input/output format
- replaces backtick "code" formatting with `{replacement}`
- no headings
- no cards at all
- minimal toolbar but all formatting is still available using markdown text expansions or keyboard shortcuts
no issue
- the card wrapper component was registering an event handler for keyboard events when entering edit mode. This was a problem because those events were also picking up the initial ctrl/cmd+enter and then immediately toggling back out of edit mode
- added a 20ms timeout for registering the event handlers so that they're not working cross-purposes
no issue
- when the mobiledoc spec changes due to a mobiledoc-kit version bump, any posts created with that version will fail to load in the editor if a rollback to an earlier Ghost version occurs
- use an explicit version to avoid the problem - we should only be bumping the mobiledoc spec version if we start using features from that version and mark it as a breaking change
closes https://github.com/TryGhost/Ghost/issues/10240
- intercept known macOS content-modifying keyboard shortcuts and simulate the "normal" keyboard events that they map to
- `ctrl+h`: `Backspace`
- `ctrl+d`: `Delete`
closes https://github.com/TryGhost/Ghost/issues/10090
- when mobiledoc-kit replaces the selection the caret window selection is temporarily set to the whole editor element which was causing our scroll-cursor-into-view routine to scroll incorrectly
- adding the guard allows the first replacement cursor change to be ignored but the second cursor change to be picked up which will do nothing if the text is on-screen, or scroll if it's off screen as normal
closes https://github.com/TryGhost/Ghost/issues/9792
- use `getClientRects()` to get separate rectangles for each line of a link and use the mouse position to find the closest one so that the toolbar can be positioned relative to that link section on that line rather than always in the middle of the editor canvas
- pass the rectangle used for positioning the link toolbar through to the link input component so that there is no jumping of position when clicking the edit button
no issue
- removes number of clicks required to insert images, especially when using the `/image` shortcut
- strips `triggerBrowse` property from the payload after inserting to avoid triggering file browse when a post with blank image cards is rendered/re-rendered
no issue
- the `willDestroyElement` hook is referencing event handlers that aren't used in the bookmark card
- stopped setting `type` in the card payload as it's not used anywhere (possible hangover from when bookmarks were a type of embed card)
no issue
- convert relative links to absolute based on the configured blog url when displaying URLs in the link toolbar and when manually setting a relative link
- converting to absolute in the editor prevents the in-memory mobiledoc getting out of sync with the server response when it converts relative urls to absolute
requires https://github.com/TryGhost/Ghost/pull/11024
With the bookmark card you can present links in a much richer format, similar to Twitter cards. If the URL points to a page with right meta information it can show the page title, excerpt, author, publisher and even a preview image.
Bookmark cards can be created in two ways:
1. pasting a link as the first thing in blank paragraph - we'll check to see if we can create an embed, if we can't then we'll create a bookmark card instead
2. manually selecting the bookmark card from the (+) menu or by typing "/bookmark<kbd>Enter</kbd>" or "/bookmark {url}<kbd>Enter</kbd>" for short (you might want to do this if you want the bookmark version instead of a full embed)
Pressing <kbd>Ctrl/Cmd+Z</kbd> after pasting will convert the bookmark card back to a link if that's preferred, alternatively a URL can be pasted with <kbd>Ctrl/Cmd+Shift+V</kbd> to avoid any automatic transformation to an embed/bookmark.
---
- adds "bookmark" card that functions similarly to the embed card
- if the oembed API request returns `type: "bookmark"` then the metadata is used to create a bookmark card
no issue
- adds an "Alt" button that is displayed in the caption input whilst an image card is selected, clicking it toggles between the rich-text caption input and a plain-text alt text input
no issue
- adjust drag handlers in the editor and gallery card to handle drag/drop of image cards as well as straight images
- adjust drag handlers in the gallery card to handle image inserts as well as re-orders
- add `onDragEnd` event/action to the Koenig drag-n-drop handler so that containers can perform cleanup if one of their draggables was successfully dropped into a different container
- change ghost element when dragging an image card to be an image rather than a card icon
- allow `createGhostElement` function passed in when registering a drag-n-drop container to fall back to the default behaviour by returning a falsy value
no issue
- update dependency `eslint-plugin-ghost` to v0.3.0
- includes new rules from `eslint-plugin-ember` 6.3.0-6.7.0
- fixed linting failures for new rules
refs. https://github.com/TryGhost/Team/issues/205
Major update to Ghost Admin UI including:
- improved general consistency (typography, colors and contrast, UI components, icons)
- new design for post and pages lists, improved discoverability of filters
- search moved to modal
- account menu is decoupled from ghost logo
- further usability fixes
no issue
- `@tryghost/kg-parser-plugins` contains the parser plugins used by the editor and was extracted so that they can be used in server-side html-to-mobiledoc conversion
no issue
- `cleanBasicHtml` has been extracted to an external package so that it can be used inside the extracted `@tryghost/kg-parser-plugins` package server-side
no issue
- Added a language indicator when in rendered mode and a language input when in edit mode
- Allow code card language to be set with <code>```lang</code>+<kbd>Space/Enter</kbd> expansion
- previously <code>\`\`\`</code> would immediately create a code card, the <kbd>Space/Enter</kbd> is now necessary for the insertion to occur
- lang is optional <code>\`\`\`</code>+<kbd>Space/Enter</kbd> will insert a code card with no language selected
- requires <kbd>Enter</kbd> to be pressed to finalise the expansion and insert the card
- added hook for text expansions to skip newline creation for when they are triggered with <kbd>Enter</kbd>
- Set the code card editor's language mode based on selected language
- set the CodeMirror mode based on the code card payload language
- add a basic map of language short codes to their respective CodeMirror modes
- observe `mode` property in `{{gh-cm-editor}}` so that the mode is properly set when it's changed after initial render
closes https://github.com/TryGhost/Ghost/issues/9847
- the text expansion is triggered twice in this situation, the first time with `""` and the second with `"/"`. The second trigger was trying to match cards to `"/"` which returned an empty card set
- added a quick workaround that ensures we never include a leading `/` in the card selection query
no issue
- added `page` model
- removed `page` param from Post model
- added pages screen with associated links
- added `:type` param to editor screens to work with the right models
- removed post<->page toggle and associated tour item
closes https://github.com/TryGhost/Ghost/issues/10399
- added a data attribute `data-koenig-dnd-disabled` which will prevent the element or any of it's children from initiating a koenig drag event
- applied the data attribute to `{{koenig-basic-html-input}}`'s outer tag so that captions never initiate a card re-order
- disabled card re-ordering when a card is in edit mode
- allows text selection within a markdown/html card without triggering the card re-order behaviour
- clicking another card will exit edit mode and re-enable drag before the drag behaviour is initiated so you can still re-order other cards if you've left a card in edit mode
no issue
- the polyfill is no longer required for latest browsers (tested on Chrome, FF, and Safari)
- Edge may have problems but it's not currently supported
- reduces build size. Before/after:
- `vendor.min.js: 3.29 MB (706 KB gzipped)`
- `vendor.min.js: 3.2 MB (672.92 KB gzipped)`
no issue
- add vertical drop position indicator handling to `koenig-drag-drop-handler` service
- fixed issues with nested drag-and-drop containers
- register card drag/drop handler in `koenig-editor`
- add drag icon creation
no issue
- clear the cached `insertIndex` when hiding the drop position indicator
- update the gallery card's `_isDropAllowed` function to return `false` if the `droppabeIndex` (`insertIndex`) doesn't exist
no issue
- when dragging an image, if you dragged out of the gallery then back in directly over the space between images then no indicator was shown
- switch to using padding around images rather than margin so that the mouse can be detected over the gap. Added classes to the image overlays to account for the change in sizing
no issue
- first pass at implementation of drag-and-drop re-ordering of images within a gallery
- adds a `koenig-drag-drop-handler` service that allows consumers (editor and cards) to hook into drag and drop behaviour without interfering with each other and allows for future possibilities such as dragging images between galleries or into/out of galleries
no issue
- use `URL.createObjectURL(file)` to get a blob url rather than using `FileReader.readAsDataURL` which generates a very large data attribute
- speeds up the display of previews and associated browser hangs when an upload finishes, especially noticeable with large images and fast connections where multiple uploads finish around the same time
closes https://github.com/TryGhost/Ghost/issues/9840
- added error on uploading an invalid image format
- updated to use overall error method(`onFailed`) to set error message instead of individual upload failures(`onUploadFailure`)
refs https://github.com/TryGhost/Ghost/issues/10049
- update `{{koenig-card}}` component to compare payload values and create a snapshot when exiting edit mode for container cards (markdown, html, code)
- update image card to trigger snapshots on image upload/selection and width change