Merged 8.9.6.
commit
a9ec667ed6
|
@ -5512,6 +5512,7 @@
|
|||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"abandoned": true,
|
||||
"time": "2017-11-27T05:48:46+00:00"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -861,7 +861,8 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
|
|||
// https://www.drupal.org/node/2504709.
|
||||
$parsed = UrlHelper::parse($request_uri);
|
||||
unset($parsed['query'][static::AJAX_FORM_REQUEST], $parsed['query'][MainContentViewSubscriber::WRAPPER_FORMAT]);
|
||||
return $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : '');
|
||||
$action = $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : '');
|
||||
return UrlHelper::filterBadProtocol($action);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -559,6 +559,7 @@
|
|||
}
|
||||
},
|
||||
dataType: 'json',
|
||||
jsonp: false,
|
||||
type: 'POST',
|
||||
};
|
||||
|
||||
|
|
|
@ -243,6 +243,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|||
},
|
||||
|
||||
dataType: 'json',
|
||||
jsonp: false,
|
||||
type: 'POST'
|
||||
};
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@
|
|||
},
|
||||
ajax: {
|
||||
dataType: 'json',
|
||||
jsonp: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -156,7 +156,8 @@
|
|||
isComposing: false
|
||||
},
|
||||
ajax: {
|
||||
dataType: 'json'
|
||||
dataType: 'json',
|
||||
jsonp: false
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -215,6 +215,9 @@
|
|||
'figcaption',
|
||||
);
|
||||
|
||||
const captionFilter = new CKEDITOR.filter(widgetDefinition.editables.caption.allowedContent);
|
||||
captionFilter.applyTo(caption);
|
||||
|
||||
// Use Drupal's data-placeholder attribute to insert a CSS-based,
|
||||
// translation-ready placeholder for empty captions. Note that it
|
||||
// also must to be done for new instances (see
|
||||
|
|
|
@ -139,6 +139,9 @@
|
|||
var figure = new CKEDITOR.htmlParser.element('figure');
|
||||
caption = new CKEDITOR.htmlParser.fragment.fromHtml(caption, 'figcaption');
|
||||
|
||||
var captionFilter = new CKEDITOR.filter(widgetDefinition.editables.caption.allowedContent);
|
||||
captionFilter.applyTo(caption);
|
||||
|
||||
caption.attributes['data-placeholder'] = placeholderText;
|
||||
|
||||
element.replaceWith(figure);
|
||||
|
|
|
@ -96,6 +96,10 @@ class ManagedFile extends FormElement {
|
|||
foreach ($input['fids'] as $fid) {
|
||||
if ($file = File::load($fid)) {
|
||||
$fids[] = $file->id();
|
||||
if (!$file->access('download')) {
|
||||
$force_default = TRUE;
|
||||
break;
|
||||
}
|
||||
// Temporary files that belong to other users should never be
|
||||
// allowed.
|
||||
if ($file->isTemporary()) {
|
||||
|
|
|
@ -92,11 +92,10 @@ class FilePrivateTest extends FileFieldTestBase {
|
|||
$this->drupalGet('node/' . $new_node->id() . '/edit');
|
||||
$this->getSession()->getPage()->find('css', 'input[name="' . $field_name . '[0][fids]"]')->setValue($node_file->id());
|
||||
$this->getSession()->getPage()->pressButton(t('Save'));
|
||||
// Make sure the form submit failed - we stayed on the edit form.
|
||||
$this->assertUrl('node/' . $new_node->id() . '/edit');
|
||||
// Check that we got the expected constraint form error.
|
||||
$constraint = new ReferenceAccessConstraint();
|
||||
$this->assertRaw(new FormattableMarkup($constraint->message, ['%type' => 'file', '%id' => $node_file->id()]));
|
||||
$this->assertUrl('node/' . $new_node->id());
|
||||
// Make sure the submitted hidden file field is empty.
|
||||
$new_node = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($new_node->id());
|
||||
$this->assertTrue($new_node->get($field_name)->isEmpty());
|
||||
// Attempt to reuse the existing file when creating a new node, and confirm
|
||||
// that access is still denied.
|
||||
$edit = [];
|
||||
|
@ -107,9 +106,10 @@ class FilePrivateTest extends FileFieldTestBase {
|
|||
$this->getSession()->getPage()->find('css', 'input[name="' . $field_name . '[0][fids]"]')->setValue($node_file->id());
|
||||
$this->getSession()->getPage()->pressButton(t('Save'));
|
||||
$new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertTrue(empty($new_node), 'Node was not created.');
|
||||
$this->assertUrl('node/add/' . $type_name);
|
||||
$this->assertRaw(new FormattableMarkup($constraint->message, ['%type' => 'file', '%id' => $node_file->id()]));
|
||||
$this->assertUrl('node/' . $new_node->id());
|
||||
// Make sure the submitted hidden file field is empty.
|
||||
$new_node = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($new_node->id());
|
||||
$this->assertTrue($new_node->get($field_name)->isEmpty());
|
||||
|
||||
// Now make file_test_file_download() return everything.
|
||||
\Drupal::state()->set('file_test.allow_all', TRUE);
|
||||
|
|
|
@ -4,9 +4,12 @@ namespace Drupal\filter\Plugin\Filter;
|
|||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\filter\FilterPluginManager;
|
||||
use Drupal\filter\FilterProcessResult;
|
||||
use Drupal\filter\Plugin\FilterBase;
|
||||
use Drupal\filter\Render\FilteredMarkup;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a filter to caption elements.
|
||||
|
@ -20,7 +23,43 @@ use Drupal\filter\Render\FilteredMarkup;
|
|||
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
|
||||
* )
|
||||
*/
|
||||
class FilterCaption extends FilterBase {
|
||||
class FilterCaption extends FilterBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* Filter manager.
|
||||
*
|
||||
* @var \Drupal\filter\FilterPluginManager
|
||||
*/
|
||||
protected $filterManager;
|
||||
|
||||
/**
|
||||
* Constructs a new FilterCaption.
|
||||
*
|
||||
* @param array $configuration
|
||||
* Configuration.
|
||||
* @param string $plugin_id
|
||||
* Plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* Definition.
|
||||
* @param \Drupal\filter\FilterPluginManager $filter_manager
|
||||
* Filter plugin manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, FilterPluginManager $filter_manager = NULL) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->filterManager = $filter_manager ?: \Drupal::service('plugin.manager.filter');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('plugin.manager.filter')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -31,6 +70,13 @@ class FilterCaption extends FilterBase {
|
|||
if (stristr($text, 'data-caption') !== FALSE) {
|
||||
$dom = Html::load($text);
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$html_filter = $this->filterManager->createInstance('filter_html', [
|
||||
'settings' => [
|
||||
'allowed_html' => '<a href hreflang target rel> <em> <strong> <cite> <code> <br>',
|
||||
'filter_html_help' => FALSE,
|
||||
'filter_html_nofollow' => FALSE,
|
||||
],
|
||||
]);
|
||||
foreach ($xpath->query('//*[@data-caption]') as $node) {
|
||||
// Read the data-caption attribute's value, then delete it.
|
||||
$caption = Html::escape($node->getAttribute('data-caption'));
|
||||
|
@ -39,10 +85,19 @@ class FilterCaption extends FilterBase {
|
|||
// Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
|
||||
// allow inline tags that are allowed by default, plus <br>.
|
||||
$caption = Html::decodeEntities($caption);
|
||||
$caption = FilteredMarkup::create(Xss::filter($caption, ['a', 'em', 'strong', 'cite', 'code', 'br']));
|
||||
$raw_caption = $caption;
|
||||
$filtered_caption = $html_filter->process($caption, $langcode);
|
||||
$result->addCacheableDependency($filtered_caption);
|
||||
$caption = FilteredMarkup::create($filtered_caption->getProcessedText());
|
||||
|
||||
// The caption must be non-empty.
|
||||
if (mb_strlen($caption) === 0) {
|
||||
// The caption must be non-empty - however the Media Embed CKEditor
|
||||
// plugin uses a single space to represent a newly added caption. The
|
||||
// HTML filter will transform this into an empty string and prevent the
|
||||
// content editor from adding a new caption. To allow for this we treat
|
||||
// a raw caption value of ' ' as valid and adding the wrapping figure
|
||||
// element.
|
||||
// @see core/modules/media/js/plugins/drupalmedia/plugin.es6.js
|
||||
if (mb_strlen($caption) === 0 && $raw_caption !== ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\user\Plugin\Block;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Security\TrustedCallbackInterface;
|
||||
|
@ -155,7 +156,7 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
|||
public static function renderPlaceholderFormAction() {
|
||||
return [
|
||||
'#type' => 'markup',
|
||||
'#markup' => Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(),
|
||||
'#markup' => UrlHelper::filterBadProtocol(Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString()),
|
||||
'#cache' => ['contexts' => ['url.path', 'url.query_args']],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -186,7 +186,11 @@ class WorkspaceManager implements WorkspaceManagerInterface {
|
|||
foreach ($this->negotiatorIds as $negotiator_id) {
|
||||
$negotiator = $this->classResolver->getInstanceFromDefinition($negotiator_id);
|
||||
if ($negotiator->applies($request)) {
|
||||
if ($active_workspace = $negotiator->getActiveWorkspace($request)) {
|
||||
// By default, 'view' access is checked when a workspace is activated,
|
||||
// but it should also be checked when retrieving the currently active
|
||||
// workspace.
|
||||
if (($negotiated_workspace = $negotiator->getActiveWorkspace($request)) && $negotiated_workspace->access('view')) {
|
||||
$active_workspace = $negotiated_workspace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\workspaces\Functional\UpdateSystem;
|
|||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
use Drupal\Tests\user\Traits\UserCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests that there is no active workspace during database updates.
|
||||
|
@ -12,12 +13,14 @@ use Drupal\Tests\UpdatePathTestTrait;
|
|||
* @group Update
|
||||
*/
|
||||
class ActiveWorkspaceUpdateTest extends BrowserTestBase {
|
||||
|
||||
use UpdatePathTestTrait;
|
||||
use UserCreationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['workspaces', 'workspace_update_test'];
|
||||
protected static $modules = ['workspaces'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -29,6 +32,11 @@ class ActiveWorkspaceUpdateTest extends BrowserTestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->setUpCurrentUser([], ['view any workspace']);
|
||||
$this->container->get('module_installer')->install(['workspace_update_test']);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Ensure the workspace_update_test_post_update_check_active_workspace()
|
||||
// update runs.
|
||||
$existing_updates = \Drupal::keyValue('post_update')->get('existing_updates', []);
|
||||
|
|
Loading…
Reference in New Issue