@amazeelabs/silverback-gutenberg 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +983 -0
- package/drupal/silverback_gutenberg/README.md +439 -0
- package/drupal/silverback_gutenberg/composer.json +20 -0
- package/drupal/silverback_gutenberg/config/install/silverback_gutenberg.settings.yml +1 -0
- package/drupal/silverback_gutenberg/config/schema/silverback_gutenberg.schema.yml +13 -0
- package/drupal/silverback_gutenberg/css/gutenberg-tweaks.css +46 -0
- package/drupal/silverback_gutenberg/directives.gql +40 -0
- package/drupal/silverback_gutenberg/directives.graphql +46 -0
- package/drupal/silverback_gutenberg/js/base.js +24 -0
- package/drupal/silverback_gutenberg/js/gutenberg-tweaks.js +154 -0
- package/drupal/silverback_gutenberg/silverback_gutenberg.api.php +76 -0
- package/drupal/silverback_gutenberg/silverback_gutenberg.info.yml +8 -0
- package/drupal/silverback_gutenberg/silverback_gutenberg.libraries.yml +14 -0
- package/drupal/silverback_gutenberg/silverback_gutenberg.module +97 -0
- package/drupal/silverback_gutenberg/silverback_gutenberg.services.yml +29 -0
- package/drupal/silverback_gutenberg/src/Annotation/GutenbergBlockMutator.php +39 -0
- package/drupal/silverback_gutenberg/src/Annotation/GutenbergValidator.php +37 -0
- package/drupal/silverback_gutenberg/src/Annotation/GutenbergValidatorRule.php +37 -0
- package/drupal/silverback_gutenberg/src/Attribute/GutenbergBlockMutator.php +29 -0
- package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorBase.php +24 -0
- package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorInterface.php +41 -0
- package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorManager.php +114 -0
- package/drupal/silverback_gutenberg/src/BlockMutator/BlockMutatorManagerInterface.php +30 -0
- package/drupal/silverback_gutenberg/src/BlockMutator/EntityBlockMutatorBase.php +189 -0
- package/drupal/silverback_gutenberg/src/BlockSerializer.php +84 -0
- package/drupal/silverback_gutenberg/src/Controller/LinkitAutocomplete.php +84 -0
- package/drupal/silverback_gutenberg/src/Directives.php +74 -0
- package/drupal/silverback_gutenberg/src/EditorBlocksProcessor.php +53 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergCardinalityValidatorInterface.php +19 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergCardinalityValidatorTrait.php +221 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorBase.php +24 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorInterface.php +65 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorManager.php +37 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorRuleInterface.php +20 -0
- package/drupal/silverback_gutenberg/src/GutenbergValidation/GutenbergValidatorRuleManager.php +37 -0
- package/drupal/silverback_gutenberg/src/LinkProcessor.php +405 -0
- package/drupal/silverback_gutenberg/src/LinkedContentExtractor.php +35 -0
- package/drupal/silverback_gutenberg/src/Normalizer/GutenbergContentEntityNormalizer.php +123 -0
- package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergContentTrackTrait.php +51 -0
- package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergLinkedContent.php +96 -0
- package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergMediaEmbed.php +63 -0
- package/drupal/silverback_gutenberg/src/Plugin/EntityUsage/Track/GutenbergReferencedContent.php +101 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockAttribute.php +42 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockChildren.php +32 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockHtml.php +30 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockMedia.php +159 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlockType.php +29 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/DataProducer/EditorBlocks.php +127 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockAttribute.php +29 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockChildren.php +21 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockMarkup.php +21 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockMedia.php +21 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlockType.php +21 -0
- package/drupal/silverback_gutenberg/src/Plugin/GraphQL/Directive/EditorBlocks.php +36 -0
- package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/MediaBlockMutator.php +30 -0
- package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/NodeBlockMutator.php +25 -0
- package/drupal/silverback_gutenberg/src/Plugin/GutenbergBlockMutator/TermReferenceBlockMutator.php +104 -0
- package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackMatcherTrait.php +69 -0
- package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackMediaMatcher.php +53 -0
- package/drupal/silverback_gutenberg/src/Plugin/Linkit/Matcher/SilverbackNodeMatcher.php +19 -0
- package/drupal/silverback_gutenberg/src/Plugin/Validation/Constraint/Gutenberg.php +15 -0
- package/drupal/silverback_gutenberg/src/Plugin/Validation/Constraint/GutenbergValidator.php +210 -0
- package/drupal/silverback_gutenberg/src/Plugin/Validation/GutenbergValidatorRule/Email.php +28 -0
- package/drupal/silverback_gutenberg/src/Plugin/Validation/GutenbergValidatorRule/Required.php +29 -0
- package/drupal/silverback_gutenberg/src/ReferencedContentExtractor.php +67 -0
- package/drupal/silverback_gutenberg/src/Routing/RouteSubscriber.php +17 -0
- package/drupal/silverback_gutenberg/src/Service/MediaService.php +27 -0
- package/drupal/silverback_gutenberg/src/SilverbackGutenbergServiceProvider.php +28 -0
- package/drupal/silverback_gutenberg/src/Utils.php +30 -0
- package/drupal/silverback_gutenberg/src/WebformMessageManager.php +29 -0
- package/drupal/silverback_gutenberg/tests/graphql/.graphqlrc.json +5 -0
- package/drupal/silverback_gutenberg/tests/graphql/queries/editor.gql +30 -0
- package/drupal/silverback_gutenberg/tests/graphql/schema.graphqls +37 -0
- package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/silverback_gutenberg_test_validator.info.yml +9 -0
- package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/ColumnValidator.php +42 -0
- package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/GroupValidator.php +50 -0
- package/drupal/silverback_gutenberg/tests/modules/silverback_gutenberg_test_validator/src/Plugin/Validation/GutenbergValidator/LinkValidator.php +43 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/BlockValidationRuleTest.php +194 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/EditorDirectivesTest.php +255 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/GutenbergLinkedContentEUTrackTest.php +133 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/GutenbergReferencedContentEUTrackTest.php +225 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/LinkProcessorTest.php +284 -0
- package/drupal/silverback_gutenberg/tests/src/Kernel/MediaNormalizerTest.php +174 -0
- package/drupal/silverback_gutenberg/tests/src/Traits/SampleAssetTrait.php +15 -0
- package/drupal/silverback_gutenberg/tests/src/Unit/BlockSerializerTest.php +27 -0
- package/drupal/silverback_gutenberg/tests/src/Unit/BlockValidatorCardinalityTest.php +1537 -0
- package/drupal/silverback_gutenberg/tests/src/Unit/EditorBlocksProcessorTest.php +159 -0
- package/drupal/silverback_gutenberg/tests/src/Unit/LinkedContentExtractorTest.php +65 -0
- package/drupal/silverback_gutenberg/tests/src/Unit/ReferencedContentExtractorTest.php +248 -0
- package/drupal/silverback_gutenberg/tests/src/assets/media/data.json +4 -0
- package/drupal/silverback_gutenberg/tests/src/assets/media/source.html +71 -0
- package/drupal/silverback_gutenberg/tests/src/assets/media/target.html +71 -0
- package/package.json +16 -0
- package/turbo.json +15 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* global drupalSettings, wp, jQuery */
|
|
2
|
+
(function ($) {
|
|
3
|
+
drupalSettings.gutenberg._listeners.init.push(
|
|
4
|
+
// For all block types:
|
|
5
|
+
function () {
|
|
6
|
+
var blockTypes = wp.blocks.getBlockTypes();
|
|
7
|
+
for (var i = 0; i < blockTypes.length; i++) {
|
|
8
|
+
if (!blockTypes[i].supports) {
|
|
9
|
+
blockTypes[i].supports = {};
|
|
10
|
+
}
|
|
11
|
+
// Disable "Additional CSS class(es)" section.
|
|
12
|
+
blockTypes[i].supports.customClassName = false;
|
|
13
|
+
// Disable align options.
|
|
14
|
+
blockTypes[i].supports.align = false;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
// Workaround for https://github.com/WordPress/gutenberg/issues/19815
|
|
19
|
+
function () {
|
|
20
|
+
var coreColumnsAllowed =
|
|
21
|
+
drupalSettings.editor.formats.gutenberg.editorSettings.allowedBlocks[
|
|
22
|
+
'core/columns'
|
|
23
|
+
];
|
|
24
|
+
var coreImageAllowed =
|
|
25
|
+
drupalSettings.editor.formats.gutenberg.editorSettings.allowedBlocks[
|
|
26
|
+
'core/image'
|
|
27
|
+
];
|
|
28
|
+
if (coreColumnsAllowed && !coreImageAllowed) {
|
|
29
|
+
var coreColumnsBlock = wp.blocks.getBlockType('core/columns');
|
|
30
|
+
// Remove core/image from the example.
|
|
31
|
+
coreColumnsBlock.example.innerBlocks[0].innerBlocks.splice(1, 1);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
// Disable fullscreen mode.
|
|
35
|
+
function () {
|
|
36
|
+
const isFullscreenMode = wp.data
|
|
37
|
+
.select('core/edit-post')
|
|
38
|
+
.isFeatureActive('fullscreenMode');
|
|
39
|
+
|
|
40
|
+
if (isFullscreenMode) {
|
|
41
|
+
wp.data.dispatch('core/edit-post').toggleFeature('fullscreenMode');
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
// Remove most of the columns options.
|
|
45
|
+
function () {
|
|
46
|
+
var coreColumnsBlock = wp.blocks.getBlockType('core/columns');
|
|
47
|
+
coreColumnsBlock.supports.inserter = false;
|
|
48
|
+
coreColumnsBlock.supports.align = false;
|
|
49
|
+
coreColumnsBlock.supports.__experimentalColor = false;
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// We never want some of the format options.
|
|
53
|
+
function () {
|
|
54
|
+
wp.richText.unregisterFormatType('core/image');
|
|
55
|
+
wp.richText.unregisterFormatType('core/text-color');
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// We don't want table styles.
|
|
59
|
+
function () {
|
|
60
|
+
wp.blocks.unregisterBlockStyle('core/table', 'regular');
|
|
61
|
+
wp.blocks.unregisterBlockStyle('core/table', 'stripes');
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Workaround for https://www.drupal.org/project/gutenberg/issues/3261702
|
|
65
|
+
function () {
|
|
66
|
+
$('.gutenberg-full-editor').on('keydown', function (event) {
|
|
67
|
+
if (
|
|
68
|
+
event &&
|
|
69
|
+
(event.code === 'Enter' || event.code === 'Space') &&
|
|
70
|
+
event.target &&
|
|
71
|
+
$(event.target).hasClass('block-editor-link-control__search-submit')
|
|
72
|
+
) {
|
|
73
|
+
var $chosenResult = $(event.target)
|
|
74
|
+
.closest('.block-editor-link-control__search-input-wrapper')
|
|
75
|
+
.find(
|
|
76
|
+
'.block-editor-link-control__search-results button[aria-selected="true"].is-entity',
|
|
77
|
+
);
|
|
78
|
+
if ($chosenResult.length) {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
$chosenResult.click();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Validators: highlight the relevant blocks and scroll to the first error.
|
|
87
|
+
function () {
|
|
88
|
+
const { select, subscribe } = wp.data;
|
|
89
|
+
|
|
90
|
+
const closeListener = subscribe(() => {
|
|
91
|
+
const isReady = select('core/editor').__unstableIsEditorReady();
|
|
92
|
+
if (!isReady) {
|
|
93
|
+
// Editor not ready.
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Close the listener as soon as we know we are ready to avoid an infinite loop.
|
|
97
|
+
closeListener();
|
|
98
|
+
|
|
99
|
+
// It seems that, even with this listener, we still need a timeout.
|
|
100
|
+
window.setTimeout(function () {
|
|
101
|
+
// Get all the validation errors based on the messages.
|
|
102
|
+
const validationErrors = {};
|
|
103
|
+
Array.from(
|
|
104
|
+
document.getElementsByClassName('block-validation-error'),
|
|
105
|
+
).forEach(function (item) {
|
|
106
|
+
const blockType = item.getAttribute('data-block-type');
|
|
107
|
+
const blockInstance = parseInt(
|
|
108
|
+
item.getAttribute('data-block-instance'),
|
|
109
|
+
);
|
|
110
|
+
if (!(blockType in validationErrors)) {
|
|
111
|
+
validationErrors[blockType] = [];
|
|
112
|
+
}
|
|
113
|
+
validationErrors[blockType].push(blockInstance);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const blockTypeInstances = {};
|
|
117
|
+
let firstErrorBlockId = null;
|
|
118
|
+
|
|
119
|
+
// Append invalid class to the relevant blocks.
|
|
120
|
+
Array.from(document.getElementsByClassName('wp-block')).forEach(
|
|
121
|
+
function (item) {
|
|
122
|
+
const blockType = item.getAttribute('data-type');
|
|
123
|
+
if (!(blockType in blockTypeInstances)) {
|
|
124
|
+
blockTypeInstances[blockType] = [];
|
|
125
|
+
}
|
|
126
|
+
blockTypeInstances[blockType].push(item);
|
|
127
|
+
if (blockType in validationErrors) {
|
|
128
|
+
const blockId = item.getAttribute('data-block');
|
|
129
|
+
const blockInstanceId = blockTypeInstances[blockType].length;
|
|
130
|
+
if (validationErrors[blockType].includes(blockInstanceId)) {
|
|
131
|
+
// Somehow, altering the item directly causes issues with
|
|
132
|
+
// the block editor. So we use jQuery instead.
|
|
133
|
+
$('div[data-block="' + blockId + '"]').addClass('not-valid');
|
|
134
|
+
if (firstErrorBlockId === null) {
|
|
135
|
+
firstErrorBlockId = blockId;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// Scroll to the first error.
|
|
143
|
+
if (firstErrorBlockId !== null) {
|
|
144
|
+
document
|
|
145
|
+
.querySelector('div[data-block="' + firstErrorBlockId + '"]')
|
|
146
|
+
.scrollIntoView({
|
|
147
|
+
behavior: 'smooth',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}, 1000);
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
);
|
|
154
|
+
})(jQuery);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use hook_silverback_gutenberg_link_processor_block_attrs_alter
|
|
5
|
+
*/
|
|
6
|
+
function hook_silverback_gutenberg_link_processor_block_attributes_alter(
|
|
7
|
+
array &$attributes,
|
|
8
|
+
string $blockName,
|
|
9
|
+
callable $processUrlCallback
|
|
10
|
+
) {
|
|
11
|
+
// Use hook_silverback_gutenberg_link_processor_block_attrs_alter() instead.
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param array $attributes
|
|
16
|
+
* @param array $context
|
|
17
|
+
* Has the following keys:
|
|
18
|
+
* - blockName: a string containing the block name
|
|
19
|
+
* - processUrlCallback: a callback to process a single URL string
|
|
20
|
+
* Callback signature: (string $url): string
|
|
21
|
+
* - processLinksCallback: a callback to process links in an HTML string
|
|
22
|
+
* Callback signature: (string $html): string
|
|
23
|
+
* - direction: "inbound" or "outbound"
|
|
24
|
+
* - language: LanguageInterface or null
|
|
25
|
+
*/
|
|
26
|
+
function hook_silverback_gutenberg_link_processor_block_attrs_alter(array &$attributes, array $context) {
|
|
27
|
+
if ($context['blockName'] === 'custom/my-links-block' && isset($attributes['urls'])) {
|
|
28
|
+
$attributes['urlsUnprocessed'] = [];
|
|
29
|
+
foreach ($attributes['urls'] as $key => $url) {
|
|
30
|
+
if ($context['direction'] === 'outbound') {
|
|
31
|
+
$attributes['urlsUnprocessed'][$key] = $url;
|
|
32
|
+
}
|
|
33
|
+
$attributes['urls'][$key] = $context['processUrlCallback']($url);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if ($context['blockName'] === 'custom/my-media-block' && isset($attributes['caption'])) {
|
|
37
|
+
$html = $attributes['caption'];
|
|
38
|
+
$attributes['caption'] = $context['processLinksCallback']($html);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function hook_silverback_gutenberg_link_processor_inbound_link_alter(
|
|
43
|
+
\DOMElement $link,
|
|
44
|
+
\Drupal\silverback_gutenberg\LinkProcessor $linkProcessor
|
|
45
|
+
) {
|
|
46
|
+
// No idea.
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hook_silverback_gutenberg_link_processor_outbound_link_alter(
|
|
50
|
+
\DOMElement $link,
|
|
51
|
+
\Drupal\Core\Language\LanguageInterface $language,
|
|
52
|
+
\Drupal\silverback_gutenberg\LinkProcessor $linkProcessor
|
|
53
|
+
) {
|
|
54
|
+
$url = $link->getAttribute('href');
|
|
55
|
+
if ($url && !$linkProcessor->linksToCurrentHost($url)) {
|
|
56
|
+
$link->setAttribute('target', '_blank');
|
|
57
|
+
$link->setAttribute('rel', 'noreferrer');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function hook_silverback_gutenberg_link_processor_inbound_url_alter(
|
|
62
|
+
string &$url,
|
|
63
|
+
\Drupal\silverback_gutenberg\LinkProcessor $linkProcessor
|
|
64
|
+
) {
|
|
65
|
+
// No idea.
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function hook_silverback_gutenberg_link_processor_outbound_url_alter(
|
|
69
|
+
string &$url,
|
|
70
|
+
\Drupal\Core\Language\LanguageInterface $language,
|
|
71
|
+
\Drupal\silverback_gutenberg\LinkProcessor $linkProcessor
|
|
72
|
+
) {
|
|
73
|
+
if (preg_match('#^/media/([0-9]+)/edit$#', $url, $matches)) {
|
|
74
|
+
// For example, turn $url into a direct file link.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Drupal\Core\Asset\AttachedAssetsInterface;
|
|
4
|
+
use Drupal\Core\Entity\EntityTypeInterface;
|
|
5
|
+
use Drupal\Core\Form\FormStateInterface;
|
|
6
|
+
use Drupal\node\NodeInterface;
|
|
7
|
+
use Drupal\silverback_gutenberg\Utils;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Implements hook_js_settings_alter().
|
|
11
|
+
*/
|
|
12
|
+
function silverback_gutenberg_js_settings_alter(array &$settings, AttachedAssetsInterface $assets) {
|
|
13
|
+
if (isset($settings['gutenberg'])) {
|
|
14
|
+
if (!isset($settings['gutenberg']['theme-support'])) {
|
|
15
|
+
$settings['gutenberg']['theme-support'] = [];
|
|
16
|
+
}
|
|
17
|
+
$settings['gutenberg']['theme-support'] = [
|
|
18
|
+
|
|
19
|
+
// Disable text colors.
|
|
20
|
+
'colors' => [],
|
|
21
|
+
'disableCustomColors' => TRUE,
|
|
22
|
+
|
|
23
|
+
// Disable typography.
|
|
24
|
+
'fontSizes' => [],
|
|
25
|
+
'disableCustomFontSizes' => TRUE,
|
|
26
|
+
'__experimentalDisableCustomLineHeight' => TRUE,
|
|
27
|
+
'__experimentalDisableDropCap' => TRUE,
|
|
28
|
+
|
|
29
|
+
] + $settings['gutenberg']['theme-support'];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Implements hook_library_info_alter().
|
|
35
|
+
*/
|
|
36
|
+
function silverback_gutenberg_library_info_alter(&$libraries, $extension) {
|
|
37
|
+
if ($extension === 'gutenberg') {
|
|
38
|
+
$libraries['edit-node']['dependencies'][] = 'silverback_gutenberg/tweaks';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Implements hook_form_BASE_FORM_ID_alter().
|
|
44
|
+
*/
|
|
45
|
+
function silverback_gutenberg_form_node_form_alter(&$form, FormStateInterface $form_state) {
|
|
46
|
+
/** @var \Drupal\node\NodeInterface $node */
|
|
47
|
+
$node = $form_state->getFormObject()->getEntity();
|
|
48
|
+
foreach (Utils::getGutenbergFields($node) as $field) {
|
|
49
|
+
if (isset($form[$field]['widget'][0]) && is_array($form[$field]['widget'][0]) && is_string($form[$field]['widget'][0]['#default_value'])) {
|
|
50
|
+
$form[$field]['widget'][0]['#default_value'] =
|
|
51
|
+
Utils::linkProcessor()->processLinks(
|
|
52
|
+
$form[$field]['widget'][0]['#default_value'],
|
|
53
|
+
'outbound',
|
|
54
|
+
\Drupal::languageManager()->getLanguage(
|
|
55
|
+
$form['langcode']['widget'][0]['value']['#default_value']
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Implements hook_ENTITY_TYPE_presave().
|
|
64
|
+
*/
|
|
65
|
+
function silverback_gutenberg_node_presave(NodeInterface $node) {
|
|
66
|
+
foreach (Utils::getGutenbergFields($node) as $field) {
|
|
67
|
+
$field = $node->get($field);
|
|
68
|
+
if (is_string($field->value)) {
|
|
69
|
+
$field->value = Utils::linkProcessor()->processLinks(
|
|
70
|
+
$field->value,
|
|
71
|
+
'inbound'
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Implements hook_silverback_gutenberg_link_processor_block_attrs_alter().
|
|
79
|
+
*/
|
|
80
|
+
function silverback_gutenberg_silverback_gutenberg_link_processor_block_attrs_alter(array &$attributes, array $context) {
|
|
81
|
+
if ($context['blockName'] === 'drupalmedia/drupal-media-entity' && isset($attributes['caption'])) {
|
|
82
|
+
$attributes['caption'] = $context['processLinksCallback']($attributes['caption']);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Implements hook_entity_bundle_field_info_alter().
|
|
88
|
+
*/
|
|
89
|
+
function silverback_gutenberg_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
|
|
90
|
+
if ($entity_type->id() === 'node') {
|
|
91
|
+
$gutenberg_config = \Drupal::config('gutenberg.settings');
|
|
92
|
+
$is_gutenberg_enabled = $gutenberg_config->get($bundle . '_enable_full');
|
|
93
|
+
if (isset($fields['body']) && $is_gutenberg_enabled) {
|
|
94
|
+
$fields['body']->addConstraint('Gutenberg', []);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
services:
|
|
2
|
+
Drupal\silverback_gutenberg\Routing\RouteSubscriber:
|
|
3
|
+
class: Drupal\silverback_gutenberg\Routing\RouteSubscriber
|
|
4
|
+
tags:
|
|
5
|
+
- { name: event_subscriber }
|
|
6
|
+
Drupal\silverback_gutenberg\LinkProcessor:
|
|
7
|
+
class: Drupal\silverback_gutenberg\LinkProcessor
|
|
8
|
+
arguments:
|
|
9
|
+
[
|
|
10
|
+
'@path_alias.manager',
|
|
11
|
+
'@config.factory',
|
|
12
|
+
'@request_stack',
|
|
13
|
+
'@module_handler',
|
|
14
|
+
'@entity.repository',
|
|
15
|
+
'@entity_type.manager',
|
|
16
|
+
]
|
|
17
|
+
plugin.manager.gutenberg_validator:
|
|
18
|
+
class: Drupal\silverback_gutenberg\GutenbergValidation\GutenbergValidatorManager
|
|
19
|
+
parent: default_plugin_manager
|
|
20
|
+
plugin.manager.gutenberg_validator_rule:
|
|
21
|
+
class: Drupal\silverback_gutenberg\GutenbergValidation\GutenbergValidatorRuleManager
|
|
22
|
+
parent: default_plugin_manager
|
|
23
|
+
silverback_gutenberg.linked_content_extractor:
|
|
24
|
+
class: \Drupal\silverback_gutenberg\LinkedContentExtractor
|
|
25
|
+
silverback_gutenberg.referenced_content_extractor:
|
|
26
|
+
class: \Drupal\silverback_gutenberg\ReferencedContentExtractor
|
|
27
|
+
plugin.manager.block_mutator:
|
|
28
|
+
class: Drupal\silverback_gutenberg\BlockMutator\BlockMutatorManager
|
|
29
|
+
parent: default_plugin_manager
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_gutenberg\Annotation;
|
|
4
|
+
|
|
5
|
+
use Drupal\Component\Annotation\Plugin;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @Annotation
|
|
9
|
+
*
|
|
10
|
+
* @deprecated
|
|
11
|
+
*/
|
|
12
|
+
class GutenbergBlockMutator extends Plugin {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The block mutator plugin ID.
|
|
16
|
+
*
|
|
17
|
+
* @var string
|
|
18
|
+
*/
|
|
19
|
+
public $id;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The human-readable name of the block mutator plugin.
|
|
23
|
+
*
|
|
24
|
+
* @ingroup plugin_translatable
|
|
25
|
+
*
|
|
26
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
27
|
+
*/
|
|
28
|
+
public $label;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The description of the block mutator plugin.
|
|
32
|
+
*
|
|
33
|
+
* @ingroup plugin_translatable
|
|
34
|
+
*
|
|
35
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
36
|
+
*/
|
|
37
|
+
public $description;
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_gutenberg\Annotation;
|
|
4
|
+
|
|
5
|
+
use Drupal\Component\Annotation\Plugin;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @Annotation
|
|
9
|
+
*/
|
|
10
|
+
class GutenbergValidator extends Plugin {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The validator plugin ID.
|
|
14
|
+
*
|
|
15
|
+
* @var string
|
|
16
|
+
*/
|
|
17
|
+
public $id;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The human-readable name of the validator plugin.
|
|
21
|
+
*
|
|
22
|
+
* @ingroup plugin_translatable
|
|
23
|
+
*
|
|
24
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
25
|
+
*/
|
|
26
|
+
public $label;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The description of the validator plugin.
|
|
30
|
+
*
|
|
31
|
+
* @ingroup plugin_translatable
|
|
32
|
+
*
|
|
33
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
34
|
+
*/
|
|
35
|
+
public $description;
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_gutenberg\Annotation;
|
|
4
|
+
|
|
5
|
+
use Drupal\Component\Annotation\Plugin;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @Annotation
|
|
9
|
+
*/
|
|
10
|
+
class GutenbergValidatorRule extends Plugin {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The validator plugin ID.
|
|
14
|
+
*
|
|
15
|
+
* @var string
|
|
16
|
+
*/
|
|
17
|
+
public $id;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The human-readable name of the validator plugin.
|
|
21
|
+
*
|
|
22
|
+
* @ingroup plugin_translatable
|
|
23
|
+
*
|
|
24
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
25
|
+
*/
|
|
26
|
+
public $label;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The description of the validator plugin.
|
|
30
|
+
*
|
|
31
|
+
* @ingroup plugin_translatable
|
|
32
|
+
*
|
|
33
|
+
* @var \Drupal\Core\Annotation\Translation
|
|
34
|
+
*/
|
|
35
|
+
public $description;
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
namespace Drupal\silverback_gutenberg\Attribute;
|
|
6
|
+
|
|
7
|
+
use Drupal\Component\Plugin\Attribute\Plugin;
|
|
8
|
+
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
|
9
|
+
|
|
10
|
+
#[\Attribute(\Attribute::TARGET_CLASS)]
|
|
11
|
+
class GutenbergBlockMutator extends Plugin {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constructs a GutenbergBlockMutator attribute.
|
|
15
|
+
*
|
|
16
|
+
* @param string $id
|
|
17
|
+
* The plugin ID.
|
|
18
|
+
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $label
|
|
19
|
+
* (optional) The human-readable name of the mutator.
|
|
20
|
+
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $description
|
|
21
|
+
* (optional) A short description of the mutator.
|
|
22
|
+
*/
|
|
23
|
+
public function __construct(
|
|
24
|
+
public readonly string $id,
|
|
25
|
+
public readonly ?TranslatableMarkup $label = NULL,
|
|
26
|
+
public readonly ?TranslatableMarkup $description = NULL,
|
|
27
|
+
) {}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_gutenberg\BlockMutator;
|
|
4
|
+
|
|
5
|
+
use Drupal\Core\Plugin\PluginBase;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Base class for the block mutator plugins. This does basically nothing on
|
|
9
|
+
* import / export, but it can be used by mutator classes that provide only one
|
|
10
|
+
* operation (import or export).
|
|
11
|
+
*/
|
|
12
|
+
abstract class BlockMutatorBase extends PluginBase implements BlockMutatorInterface {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* {@inheritDoc}
|
|
16
|
+
*/
|
|
17
|
+
public function mutateExport(array &$block, array &$dependencies): void {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* {@inheritDoc}
|
|
21
|
+
*/
|
|
22
|
+
public function mutateImport(array &$block): void {}
|
|
23
|
+
|
|
24
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_gutenberg\BlockMutator;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interface for block mutator plugins.
|
|
7
|
+
*/
|
|
8
|
+
interface BlockMutatorInterface {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the $block sent as parameter should be mutated.
|
|
12
|
+
*
|
|
13
|
+
* @param array $block
|
|
14
|
+
* The gutenberg block being processed.
|
|
15
|
+
* @return bool
|
|
16
|
+
*/
|
|
17
|
+
public function applies(array $block): bool;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Mutates the gutenberg block before it is exported by the default content
|
|
21
|
+
* module.
|
|
22
|
+
*
|
|
23
|
+
* @param array $block
|
|
24
|
+
* The gutenberg block being processed. The changes should be done directly
|
|
25
|
+
* on the block.
|
|
26
|
+
* @param array $dependencies
|
|
27
|
+
* An array of dependencies for this block. Each key of the array should be
|
|
28
|
+
* a uuid and the value should be the corresponding entity type. Example:
|
|
29
|
+
* $dependencies['some-uuid'] = 'media';
|
|
30
|
+
*/
|
|
31
|
+
public function mutateExport(array &$block, array &$dependencies): void;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Mutates the gutenberg block before it gets imported.
|
|
35
|
+
*
|
|
36
|
+
* @param array $block
|
|
37
|
+
* The gutenberg block being processed. The changes should be done directly
|
|
38
|
+
* on the block.
|
|
39
|
+
*/
|
|
40
|
+
public function mutateImport(array &$block): void;
|
|
41
|
+
}
|