Commit 3a6d0753 authored by Enrique Alcántara's avatar Enrique Alcántara Committed by Markus Koller

Document Content Editor component and Wiki integration

parent bc6d1e35
......@@ -17,7 +17,11 @@ export default {
};
</script>
<template>
<div class="md-area" :class="{ 'is-focused': contentEditor.tiptapEditor.isFocused }">
<div
data-testid="content-editor"
class="md-area"
:class="{ 'is-focused': contentEditor.tiptapEditor.isFocused }"
>
<top-toolbar class="gl-mb-4" :content-editor="contentEditor" />
<tiptap-editor-content class="md" :editor="contentEditor.tiptapEditor" />
</div>
......
......@@ -441,6 +441,7 @@ Pritaly
Priyanka
profiler
Prometheus
ProseMirror
protobuf
protobufs
proxied
......@@ -642,6 +643,7 @@ timeboxed
timeboxes
timeboxing
timecop
tiptap
todos
tokenizer
Tokenizers
......
---
stage: Create
group: Editor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Content Editor **(FREE)**
The Content Editor is a UI component that provides a WYSIWYG editing
experience for [GitLab Flavored Markdown](../../user/markdown.md) (GFM) in the GitLab application.
It also serves as the foundation for implementing Markdown-focused editors
that target other engines, like static site generators.
We use [tiptap 2.0](https://www.tiptap.dev/) and [ProseMirror](https://prosemirror.net/)
to build the Content Editor. These frameworks provide a level of abstraction on top of
the native
[`contenteditable`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content) web technology.
## Architecture remarks
At a high level, the Content Editor:
- Imports arbitrary Markdown.
- Renders it in a HTML editing area.
- Exports it back to Markdown with changes introduced by the user.
The Content Editor relies on the
[Markdown API endpoint](../../api/markdown.md) to transform Markdown
into HTML. It sends the Markdown input to the REST API and displays the API's
HTML output in the editing area. The editor exports the content back to Markdown
using a client-side library that serializes editable documents into Markdown.
![Content Editor high level diagram](img/content_editor_highlevel_diagram.png)
Check the [Content Editor technical design document](https://docs.google.com/document/d/1fKOiWpdHned4KOLVOOFYVvX1euEjMP5rTntUhpapdBg)
for more information about the design decisions that drive the development of the editor.
**NOTE**: We also designed the Content Editor to be extensible. We intend to provide
more information about extension development for supporting new types of content in upcoming
milestones.
## GitLab Flavored Markdown support
The [GitLab Flavored Markdown](../../user/markdown.md) extends
the [CommonMark specification](https://spec.commonmark.org/0.29/) with support for a
variety of content types like diagrams, math expressions, and tables. Supporting
all GitLab Flavored Markdown content types in the Content Editor is a work in progress. For
the status of the ongoing development for CommonMark and GitLab Flavored Markdown support, read:
- [Basic Markdown formatting extensions](https://gitlab.com/groups/gitlab-org/-/epics/5404) epic.
- [GitLab Flavored Markdown extensions](https://gitlab.com/groups/gitlab-org/-/epics/5438) epic.
## Usage
To include the Content Editor in your feature, import the `createContentEditor` factory
function and the `ContentEditor` Vue component. `createContentEditor` sets up an instance
of [tiptap's Editor class](https://www.tiptap.dev/api/editor) with all the necessary
extensions to support editing GitLab Flavored Markdown content. It also creates
a Markdown serializer that allows exporting tiptap's document format to Markdown.
`createContentEditor` requires a `renderMarkdown` parameter invoked
by the editor every time it needs to convert Markdown to HTML. The Content Editor
does not provide a default value for this function yet.
**NOTE**: The Content Editor is in an early development stage. Usage and development
guidelines are subject to breaking changes in the upcoming months.
```html
<script>
import { GlButton } from '@gitlab/ui';
import { createContentEditor, ContentEditor } from '~/content_editor';
import { __ } from '~/locale';
import createFlash from '~/flash';
export default {
components: {
ContentEditor,
GlButton,
},
data() {
return {
contentEditor: null,
}
},
created() {
this.contentEditor = createContentEditor({
renderMarkdown: (markdown) => Api.markdown({ text: markdown }),
});
try {
await this.contentEditor.setSerializedContent(this.content);
} catch (e) {
createFlash(__('There was an error loading content in the editor'), e);
}
},
methods: {
async save() {
await Api.updateContent({
content: this.contentEditor.getSerializedContent(),
});
},
},
};
</script>
<template>
<div>
<content-editor :content-editor="contentEditor" />
<gl-button @click="save()">Save</gl-button>
</div>
</template>
```
Call `setSerializedContent` to set initial Markdown in the Editor. This method is
asynchronous because it makes an API request to render the Markdown input.
`getSerializedContent` returns a Markdown string that represents the serialized
version of the editable document.
......@@ -93,6 +93,11 @@ General information about frontend [dependencies](dependencies.md) and how we ma
How we implement [keyboard shortcuts](keyboard_shortcuts.md) that can be customized and disabled.
## Editors
GitLab text editing experiences are provided by the [Source Editor](editor_lite.md) and
the [Content Editor](content_editor.md).
## Frontend FAQ
Read the [frontend's FAQ](frontend_faq.md) for common small pieces of helpful information.
......
......@@ -252,7 +252,7 @@ You can now see the **External wiki** option from your project's
left sidebar.
When you enable this integration, the link to the external
wiki won't replace the link to the internal wiki.
wiki doesn't replace the link to the internal wiki.
To hide the internal wiki from the sidebar, [disable the project's wiki](#disable-the-projects-wiki).
To hide the link to an external wiki:
......@@ -281,6 +281,39 @@ Previously added wiki pages are preserved in case you
want to re-enable the wiki. To re-enable it, repeat the process
to disable the wiki but toggle it on (in blue).
## Content Editor **(FREE)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5643) in GitLab 14.0.
GitLab version 14.0 introduces a WYSIWYG editing experience for GitLab Flavored Markdown
in Wikis through the [Content Editor](../../../development/fe_guide/content_editor.md).
The Content Editor is under active development, and is not yet the default editing
experience in the Wiki. To opt in for the new editor:
1. Create a new wiki page, or edit an existing one.
1. Ensure the wiki page uses the Markdown format. Other formats are not yet supported.
1. Below the **Format** select box, select **Use new editor**:
![Use new editor button image](img/use_new_editor_button_v14.0.png)
### Use the Content Editor
1. [Create](#create-a-new-wiki-page) a new wiki page, or [edit](#edit-a-wiki-page) an existing one.
1. Select **Markdown** as your format.
1. Below the **Format** select box, select **Use new editor**.
1. Customize your page's content using the various formatting options available in the content editor.
1. Select **Create page** for a new page, or **Save changes** for an existing page:
![Content Editor in Wikis image](img/content_editor_v14.0.png)
### Switch back to the old editor
1. *If you're editing the page in the content editor,* scroll to **Format**.
1. Select **Switch to old editor**.
1. Select **Switch to old editor** in the confirmation popup to confirm.
When you switch back to the old editor, any unsaved changes are lost.
## Resources
- [Wiki settings for administrators](../../../administration/wikis/index.md)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Wiki', :js do
include DocsScreenshotHelpers
include WikiHelpers
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, creator: user) }
let(:wiki) { create(:project_wiki, user: user, project: project) }
before do
page.driver.browser.manage.window.resize_to(1366, 1024)
sign_in(user)
visit wiki_path(wiki)
click_link "Create your first page"
end
context 'switching to content editor' do
it 'user/project/wiki/img/use_new_editor_button' do
screenshot_area = find('.js-quick-submit')
scroll_to screenshot_area
expect(screenshot_area).to have_content 'Use new editor'
set_crop_data(screenshot_area, 10)
end
end
context 'content editor' do
it 'user/project/wiki/img/content_editor' do
content_editor_testid = '[data-testid="content-editor"]'
click_button 'Use new editor'
expect(page).to have_css(content_editor_testid)
screenshot_area = find(content_editor_testid)
scroll_to screenshot_area
find("#{content_editor_testid} [contenteditable]").send_keys '## Using the Content Editor'
set_crop_data(screenshot_area, 50)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment