diff --git a/core/modules/edit/css/edit.css b/core/modules/edit/css/edit.css
deleted file mode 100644
index 65c7f38..0000000
--- a/core/modules/edit/css/edit.css
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * Animations.
- */
-.edit-animate-invisible {
- opacity: 0;
-}
-
-.edit-animate-fast {
--webkit-transition: all .2s ease;
- -moz-transition: all .2s ease;
- -ms-transition: all .2s ease;
- -o-transition: all .2s ease;
- transition: all .2s ease;
-}
-
-.edit-animate-default {
- -webkit-transition: all .4s ease;
- -moz-transition: all .4s ease;
- -ms-transition: all .4s ease;
- -o-transition: all .4s ease;
- transition: all .4s ease;
-}
-
-.edit-animate-slow {
--webkit-transition: all .6s ease;
- -moz-transition: all .6s ease;
- -ms-transition: all .6s ease;
- -o-transition: all .6s ease;
- transition: all .6s ease;
-}
-
-.edit-animate-delay-veryfast {
- -webkit-transition-delay: .05s;
- -moz-transition-delay: .05s;
- -ms-transition-delay: .05s;
- -o-transition-delay: .05s;
- transition-delay: .05s;
-}
-
-.edit-animate-delay-fast {
- -webkit-transition-delay: .2s;
- -moz-transition-delay: .2s;
- -ms-transition-delay: .2s;
- -o-transition-delay: .2s;
- transition-delay: .2s;
-}
-
-.edit-animate-disable-width {
- -webkit-transition: width 0s;
- -moz-transition: width 0s;
- -ms-transition: width 0s;
- -o-transition: width 0s;
- transition: width 0s;
-}
-
-.edit-animate-only-visibility {
- -webkit-transition: opacity .2s ease;
- -moz-transition: opacity .2s ease;
- -ms-transition: opacity .2s ease;
- -o-transition: opacity .2s ease;
- transition: opacity .2s ease;
-}
-
-.edit-animate-only-background-and-padding {
- -webkit-transition: background, padding .2s ease;
- -moz-transition: background, padding .2s ease;
- -ms-transition: background, padding .2s ease;
- -o-transition: background, padding .2s ease;
- transition: background, padding .2s ease;
-}
-
-
-
-/**
- * Toolbar.
- */
-.icon-edit:before {
- background-image: url("../images/icon-edit.png");
-}
-.icon-edit:active:before,
-.active .icon-edit:before {
- background-image: url("../images/icon-edit-active.png");
-}
-.toolbar .tray.edit.active {
- z-index: 340;
-}
-.toolbar .icon-edit.edit-nothing-editable-hidden {
- display: none;
-}
-/* In-place editing doesn't work in the overlay, so always hide the tab. */
-.overlay-open .toolbar .icon-edit {
- display: none;
-}
-
-
-
-/**
- * Edit mode: overlay + candidate editables + editables being edited.
- *
- * Note: every class is prefixed with "edit-" to prevent collisions with modules
- * or themes. In IPE-specific DOM subtrees, this is not necessary.
- */
-
-#edit_overlay {
- position: fixed;
- z-index: 250;
- width: 100%;
- height: 100%;
- background-color: #fff;
- background-color: rgba(255,255,255,.5);
- top: 0;
- left: 0;
-}
-
-/* Editable. */
-.edit-editable {
- z-index: 300;
- position: relative;
-}
-.edit-editable:focus {
- outline: none;
-}
-.edit-field.edit-editable,
-.edit-field.edit-type-direct .edit-editable {
- box-shadow: 0 0 1px 1px #4d9de9;
-}
-
-/* Highlighted (hovered) editable. */
-.edit-editable.edit-highlighted {
- min-width: 200px;
-}
-.edit-field.edit-editable.edit-highlighted,
-.edit-form.edit-editable.edit-highlighted,
-.edit-field.edit-type-direct .edit-editable.edit-highlighted {
- box-shadow: 0 0 1px 1px #0199ff, 0 0 3px 3px rgba(153, 153, 153, .5);
-}
-.edit-field.edit-editable.edit-highlighted.edit-validation-error,
-.edit-form.edit-editable.edit-highlighted.edit-validation-error,
-.edit-field.edit-type-direct .edit-editable.edit-highlighted.edit-validation-error {
- box-shadow: 0 0 1px 1px red, 0 0 3px 3px rgba(153, 153, 153, .5);
-}
-.edit-form.edit-editable .form-item .error {
- border: 1px solid #eea0a0;
-}
-
-
-/* Editing (focused) editable. */
-.edit-form.edit-editable.edit-editing,
-.edit-field.edit-type-direct .edit-editable.edit-editing {
- /* In the latest design, there's no special styling when editing as opposed to
- * just hovering.
- * This will be necessary again for http://drupal.org/node/1844220.
- */
-}
-
-
-
-
-/**
- * Edit mode: modal.
- */
-#edit_modal {
- z-index: 350;
- position: fixed;
- top: 40%;
- left: 40%;
- box-shadow: 3px 3px 5px #333;
- background-color: white;
- border: 1px solid #0199ff;
- font-family: 'Droid sans', 'Lucida Grande', sans-serif;
-}
-
-#edit_modal .main {
- font-size: 130%;
- margin: 25px;
- padding-left: 40px;
- background: transparent url('../images/attention.png') no-repeat;
-}
-
-#edit_modal .actions {
- border-top: 1px solid #ddd;
- padding: 3px inherit;
- text-align: right;
- background: #f5f5f5;
-}
-
-/* Modal active: prevent user from interacting with toolbar & editables. */
-.edit-form-container.edit-belowoverlay,
-.edit-toolbar-container.edit-belowoverlay,
-.edit-validation-errors.edit-belowoverlay {
- z-index: 210;
-}
-.edit-editable.edit-belowoverlay {
- z-index: 200;
-}
-
-
-
-
-/**
- * Edit mode: type=direct.
- */
-.edit-validation-errors {
- z-index: 300;
- position: relative;
-}
-
-.edit-validation-errors .messages.error {
- position: absolute;
- top: 6px;
- left: -5px;
- margin: 0;
- border: none;
- box-shadow: 0 0 1px 1px red, 0 0 3px 3px rgba(153, 153, 153, .5);
- background-color: white;
-}
-
-
-
-
-/**
- * Edit mode: type=form.
- */
-#edit_backstage {
- display: none;
-}
-
-.edit-form {
- position: absolute;
- z-index: 300;
- box-shadow: 0 0 30px 4px #4f4f4f;
- max-width: 35em;
-}
-
-.edit-form .placeholder {
- min-height: 22px;
-}
-
-/* Default form styling overrides. */
-.edit-form form { padding: 1em; }
-.edit-form .form-item { margin: 0; }
-.edit-form .form-wrapper { margin: .5em; }
-.edit-form .form-wrapper .form-wrapper { margin: inherit; }
-.edit-form .form-actions { display: none; }
-.edit-form input { max-width: 100%; }
-
-
-
-
-/**
- * Edit mode: toolbars
- */
-
-/* Trick: wrap statically positioned elements in relatively positioned element
- without changing its location. This allows us to absolutely position the
- toolbar.
-*/
-.edit-toolbar-container,
-.edit-form-container {
- position: relative;
- padding: 0;
- border: 0;
- margin: 0;
- vertical-align: baseline;
- z-index: 310;
-}
-.edit-toolbar-container {
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- -o-user-select: none;
- user-select: none;
-}
-
-.edit-toolbar-heightfaker {
- height: auto;
- position: absolute;
- bottom: 1px;
- box-shadow: 0 0 1px 1px #0199ff, 0 0 3px 3px rgba(153, 153, 153, .5);
- background: #fff;
-}
-
-/* The toolbar; these are not necessarily visible. */
-.edit-toolbar {
- position: relative;
- height: 100%;
- font-family: 'Droid sans', 'Lucida Grande', sans-serif;
-}
-.edit-toolbar-heightfaker {
- clip: rect(-1000px, 1000px, auto, -1000px); /* Remove bottom box-shadow. */
-}
-/* Exception: when used for a directly WYSIWYG editable field that is actively
- being edited. */
-.edit-type-direct-with-wysiwyg .edit-editing .edit-toolbar-heightfaker {
- width: 100%;
- clip: auto;
-}
-
-
-/* The toolbar contains toolgroups; these are visible. */
-.edit-toolgroup {
- float: left; /* LTR */
-}
-
-/* Info toolgroup. */
-.edit-toolgroup.info {
- float: left; /* LTR */
- font-weight: bolder;
- padding: 0 5px;
- background: #fff url('../images/throbber.gif') no-repeat -60px 60px;
-}
-.edit-toolgroup.info.loading {
- padding-right: 35px;
- background-position: 90% 50%;
-}
-
-/* Operations toolgroup. */
-.edit-toolgroup.ops {
- float: right; /* LTR */
- margin-left: 5px;
-}
-
-.edit-toolgroup.wysiwyg-tabs {
- float: right;
-}
-.edit-toolgroup.wysiwyg {
- clear: left;
- width: 100%;
- padding-left: 0;
-}
-
-
-
-/**
- * Edit mode: buttons (in both modal and toolbar).
- */
-#edit_modal button,
-.edit-toolbar button {
- float: left; /* LTR */
- display: block;
- height: 29px;
- min-width: 29px;
- padding: 3px 6px 6px 6px;
- margin: 4px 5px 1px 0;
- border: 1px solid #fff;
- border-radius: 3px;
- color: white;
- text-decoration: none;
- font-size: 13px;
- cursor: pointer;
-}
-#edit_modal button {
- float: none;
- display: inline-block;
-}
-
-/* Button with icons. */
-#edit_modal button span,
-.edit-toolbar button span {
- width: 22px;
- height: 19px;
- display: block;
- float: left;
-}
-.edit-toolbar span.close {
- background: url('../images/close.png') no-repeat 3px 2px;
- text-indent: -999em;
- direction: ltr;
-}
-
-.edit-toolbar button.blank-button {
- color: black;
- background-color: #fff;
- font-weight: bolder;
-}
-
-#edit_modal button.blue-button,
-.edit-toolbar button.blue-button {
- color: white;
- background-image: -webkit-linear-gradient(top, #6fc2f2 0%, #4e97c0 100%);
- background-image: -moz-linear-gradient(top, #6fc2f2 0%, #4e97c0 100%);
- background-image: linear-gradient(top, #6fc2f2 0%, #4e97c0 100%);
- border-radius: 5px;
-}
-
-#edit_modal button.gray-button,
-.edit-toolbar button.gray-button {
- color: #666;
- background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #ccc 100%);
- background-image: -moz-linear-gradient(top, #f5f5f5 0%, #ccc 100%);
- background-image: linear-gradient(top, #f5f5f5 0%, #ccc 100%);
- border-radius: 5px;
-}
-
-#edit_modal button.blue-button:hover,
-.edit-toolbar button.blue-button:hover,
-#edit_modal button.blue-button:active,
-.edit-toolbar button.blue-button:active {
- border: 1px solid #55a5d3;
- box-shadow: 0 2px 1px rgba(0,0,0,0.2);
-}
-
-#edit_modal button.gray-button:hover,
-.edit-toolbar button.gray-button:hover,
-#edit_modal button.gray-button:active,
-.edit-toolbar button.gray-button:active {
- border: 1px solid #cdcdcd;
- box-shadow: 0 2px 1px rgba(0,0,0,0.1);
-}
diff --git a/core/modules/edit/edit.info b/core/modules/edit/edit.info
deleted file mode 100644
index 4074a7b..0000000
--- a/core/modules/edit/edit.info
+++ /dev/null
@@ -1,6 +0,0 @@
-name = Edit
-description = In-place content editing.
-package = Core
-core = 8.x
-version = VERSION
-dependencies[] = field
diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module
deleted file mode 100644
index e3beec0..0000000
--- a/core/modules/edit/edit.module
+++ /dev/null
@@ -1,159 +0,0 @@
- array(
- 'title' => t('Access in-place editing'),
- ),
- );
-}
-
-/**
- * Implements hook_toolbar().
- */
-function edit_toolbar() {
- if (!user_access('access in-place editing')) {
- return;
- }
-
- $tab['edit'] = array(
- 'tab' => array(
- 'title' => t('Edit'),
- 'href' => '',
- 'html' => FALSE,
- 'attributes' => array(
- 'class' => array('icon', 'icon-edit', 'edit-nothing-editable-hidden'),
- ),
- ),
- 'tray' => array(
- '#attached' => array(
- 'library' => array(
- array('edit', 'edit'),
- ),
- ),
- ),
- );
-
- // Include the attachments and settings for all available editors.
- $attachments = drupal_container()->get('edit.editor.selector')->getAllEditorAttachments();
- $tab['edit']['tray']['#attached'] = array_merge_recursive($tab['edit']['tray']['#attached'], $attachments);
-
- return $tab;
-}
-
-/**
- * Implements hook_library().
- */
-function edit_library_info() {
- $path = drupal_get_path('module', 'edit');
- $options = array(
- 'scope' => 'footer',
- 'attributes' => array('defer' => TRUE),
- );
- $libraries['edit'] = array(
- 'title' => 'Edit: in-place editing',
- 'website' => 'http://drupal.org/project/edit',
- 'version' => VERSION,
- 'js' => array(
- // Core.
- $path . '/js/edit.js' => $options,
- $path . '/js/app.js' => $options,
- // Routers.
- $path . '/js/routers/edit-router.js' => $options,
- // Models.
- $path . '/js/models/edit-app-model.js' => $options,
- // Views.
- $path . '/js/views/propertyeditordecoration-view.js' => $options,
- $path . '/js/views/menu-view.js' => $options,
- $path . '/js/views/modal-view.js' => $options,
- $path . '/js/views/overlay-view.js' => $options,
- $path . '/js/views/toolbar-view.js' => $options,
- // Backbone.sync implementation on top of Drupal forms.
- $path . '/js/backbone.drupalform.js' => $options,
- // VIE service.
- $path . '/js/viejs/EditService.js' => $options,
- // Create.js subclasses.
- $path . '/js/createjs/editable.js' => $options,
- $path . '/js/createjs/storage.js' => $options,
- $path . '/js/createjs/editingWidgets/formwidget.js' => $options,
- $path . '/js/createjs/editingWidgets/drupalcontenteditablewidget.js' => $options,
- // Other.
- $path . '/js/util.js' => $options,
- $path . '/js/theme.js' => $options,
- // Basic settings.
- array(
- 'data' => array('edit' => array(
- 'metadataURL' => url('edit/metadata'),
- 'fieldFormURL' => url('edit/form/!entity_type/!id/!field_name/!langcode/!view_mode'),
- 'rerenderProcessedTextURL' => url('edit/text/!entity_type/!id/!field_name/!langcode/!view_mode'),
- 'context' => 'body',
- )),
- 'type' => 'setting',
- ),
- ),
- 'css' => array(
- $path . '/css/edit.css' => array(),
- ),
- 'dependencies' => array(
- array('system', 'jquery'),
- array('system', 'underscore'),
- array('system', 'backbone'),
- array('system', 'vie.core'),
- array('system', 'create.editonly'),
- array('system', 'jquery.form'),
- array('system', 'drupal.form'),
- array('system', 'drupal.ajax'),
- array('system', 'drupalSettings'),
- ),
- );
-
- return $libraries;
-}
-
-/**
- * Implements hook_preprocess_HOOK() for field.tpl.php.
- */
-function edit_preprocess_field(&$variables) {
- $element = $variables['element'];
- $entity = $element['#object'];
- $variables['attributes']['data-edit-id'] = $entity->entityType() . ':' . $entity->id() . ':' . $element['#field_name'] . ':' . $element['#language'] . ':' . $element['#view_mode'];
-}
-
-/**
- * Form constructor for the field editing form.
- *
- * @ingroup forms
- */
-function edit_field_form(array $form, array &$form_state, EntityInterface $entity, $field_name) {
- $form_handler = new EditFieldForm();
- return $form_handler->build($form, $form_state, $entity, $field_name);
-}
diff --git a/core/modules/edit/edit.routing.yml b/core/modules/edit/edit.routing.yml
deleted file mode 100644
index f63dc82..0000000
--- a/core/modules/edit/edit.routing.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-edit_metadata:
- pattern: '/edit/metadata'
- defaults:
- _controller: '\Drupal\edit\EditController::metadata'
- requirements:
- _permission: 'access in-place editing'
-
-edit_field_form:
- pattern: '/edit/form/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode}'
- defaults:
- _controller: '\Drupal\edit\EditController::fieldForm'
- requirements:
- _permission: 'access in-place editing'
- _access_edit_entity_field: 'TRUE'
-
-edit_text:
- pattern: '/edit/text/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode}'
- defaults:
- _controller: '\Drupal\edit\EditController::getUntransformedText'
- requirements:
- _permission: 'access in-place editing'
- _access_edit_entity_field: 'TRUE'
diff --git a/core/modules/edit/images/attention.png b/core/modules/edit/images/attention.png
deleted file mode 100644
index 6a35d1d..0000000
--- a/core/modules/edit/images/attention.png
+++ /dev/null
@@ -1,4 +0,0 @@
-PNG
-
-
IHDR *} `PLTEl՟FZݱ|В8 ʂx՜nϏ۫@EN;[cgUH7
tRNS =g-
Su -4_ IDATx^}ʇ @Qzn /g!ul6
; 0!f>>Ǐ kν_j㜻!0-@>8,i vҤrlWn?B(ijk*yT%Pv s=b_v>@?k&
-a|NciKBFUD^']d`5+5P
: IENDB`
\ No newline at end of file
diff --git a/core/modules/edit/images/close.png b/core/modules/edit/images/close.png
deleted file mode 100644
index e3f98b8..0000000
--- a/core/modules/edit/images/close.png
+++ /dev/null
@@ -1,4 +0,0 @@
-PNG
-
-
IHDR (-S `PLTE >+ tRNS```00 mi IDATx^= H4ͼ!KsfQGx"LCyל(ux;z
KA.Jo
-E wy/2cdD@ҔLO%8F ?Q IENDB`
\ No newline at end of file
diff --git a/core/modules/edit/images/icon-edit-active.png b/core/modules/edit/images/icon-edit-active.png
deleted file mode 100644
index ad84761..0000000
--- a/core/modules/edit/images/icon-edit-active.png
+++ /dev/null
@@ -1,3 +0,0 @@
-PNG
-
-
IHDR j `PLTE [ tRNS@ P00p`ϟ Dƙ IDATxe DQ8Ϩ/BDU9xV+D\?x@qWcF8wicS B}?v;Vf.V$JgX=Kضp0XS"iRw\:LL\~;Z5wu 5E)L IENDB`
\ No newline at end of file
diff --git a/core/modules/edit/images/icon-edit.png b/core/modules/edit/images/icon-edit.png
deleted file mode 100644
index 4f0dcc2..0000000
--- a/core/modules/edit/images/icon-edit.png
+++ /dev/null
@@ -1,5 +0,0 @@
-PNG
-
-
IHDR j PLTE̻ʪ̡̜ˠ̣̽¼Ƿ ʨªZ(e +tRNSϟ `π@`0p0p`0Pϟϟ c IDATxeW0 {W
-H"ʵ,y{Hpyo?mf,RBRxBvL;&LPJaRb\(Tbn(1wϔJ)ԈkS
-58äT^4 P6c}[i <ާ'-+HP>K IENDB`
\ No newline at end of file
diff --git a/core/modules/edit/images/throbber.gif b/core/modules/edit/images/throbber.gif
deleted file mode 100644
index f2603e8..0000000
--- a/core/modules/edit/images/throbber.gif
+++ /dev/null
@@ -1,6 +0,0 @@
-GIF89a Ž{{{ !NETSCAPE2.0 ! , @`)KkŏA|ad0L9~\8L Ǹ0, i{qBC~H'JRĨ`f4&a ! , `sɺ(t34M!-0,l#))9 !q(i<hB 3˥ (`
,9%cm
-b0AY_e ! , dRj:ړtG8$c02P hi, ǑQ0X[LEck5`ڭP2F!
a @q dfz{lQ zK ! , `BjR:$BPFq(ˢ J@0i-2͇ Qck6[G`m:pQ4fqow ! , d1j}MS@S\ H9 #IrPØi8f..r$ł|nl
-*T\![͂l,Q0@(KFMO{
ql{ ! , ^I 3a!P(Ol~`8 LÇ!@$Lgx|f,`"`Jʼn"cUP
-GAw< tz ! , h9C 4kk\
&I&l
)F-P@chH!ш4<
- x@R`0C"8h0BfgX(rc}Y
-1 ! , aйҚX]mKl[)"aĢ\*"$t	@1pP`,`I,8 S 8U,Q`(d`3-qH$1T{ ;
\ No newline at end of file
diff --git a/core/modules/edit/js/app.js b/core/modules/edit/js/app.js
deleted file mode 100644
index 00bba20..0000000
--- a/core/modules/edit/js/app.js
+++ /dev/null
@@ -1,528 +0,0 @@
-/**
- * @file
- * A Backbone View that is the central app controller.
- */
-(function ($, _, Backbone, Drupal, VIE) {
-
-"use strict";
-
- Drupal.edit = Drupal.edit || {};
- Drupal.edit.EditAppView = Backbone.View.extend({
- vie: null,
- domService: null,
-
- // Configuration for state handling.
- states: [],
- activeEditorStates: [],
- singleEditorStates: [],
-
- // State.
- $entityElements: null,
-
- /**
- * Implements Backbone Views' initialize() function.
- */
- initialize: function() {
- _.bindAll(this, 'appStateChange', 'acceptEditorStateChange', 'editorStateChange');
-
- // VIE instance for Edit.
- this.vie = new VIE();
- // Use our custom DOM parsing service until RDFa is available.
- this.vie.use(new this.vie.EditService());
- this.domService = this.vie.service('edit');
-
- // Instantiate configuration for state handling.
- this.states = [
- null, 'inactive', 'candidate', 'highlighted',
- 'activating', 'active', 'changed', 'saving', 'saved', 'invalid'
- ];
- this.activeEditorStates = ['activating', 'active'];
- this.singleEditorStates = _.union(['highlighted'], this.activeEditorStates);
-
- this.$entityElements = $([]);
-
- // Use Create's Storage widget.
- this.$el.createStorage({
- vie: this.vie,
- editableNs: 'createeditable'
- });
-
- // Instantiate OverlayView.
- var overlayView = new Drupal.edit.views.OverlayView({
- el: (Drupal.theme('editOverlay', {})),
- model: this.model
- });
-
- // Instantiate MenuView.
- var editMenuView = new Drupal.edit.views.MenuView({
- el: this.el,
- model: this.model
- });
-
- // When view/edit mode is toggled in the menu, update the editor widgets.
- this.model.on('change:isViewing', this.appStateChange);
- },
-
- /**
- * Finds editable properties within a given context.
- *
- * Finds editable properties, registers them with the app, updates their
- * state to match the current app state.
- *
- * @param $context
- * A jQuery-wrapped context DOM element within which will be searched.
- */
- findEditableProperties: function($context) {
- var that = this;
- var newState = (this.model.get('isViewing')) ? 'inactive' : 'candidate';
-
- this.domService.findSubjectElements($context).each(function() {
- var $element = $(this);
-
- // Ignore editable properties for which we've already set up Create.js.
- if (that.$entityElements.index($element) !== -1) {
- return;
- }
-
- $element
- // Instantiate an EditableEntity widget.
- .createEditable({
- vie: that.vie,
- disabled: true,
- state: 'inactive',
- acceptStateChange: that.acceptEditorStateChange,
- statechange: function(event, data) {
- that.editorStateChange(data.previous, data.current, data.propertyEditor);
- },
- decoratePropertyEditor: function(data) {
- that.decorateEditor(data.propertyEditor);
- }
- })
- // This event is triggered just before Edit removes an EditableEntity
- // widget, so that we can do proper clean-up.
- .on('destroyedPropertyEditor.edit', function(event, editor) {
- that.undecorateEditor(editor);
- that.$entityElements = that.$entityElements.not($(this));
-
- })
- // Transition the new PropertyEditor into the current state.
- .createEditable('setState', newState);
-
- // Add this new EditableEntity widget element to the list.
- that.$entityElements = that.$entityElements.add($element);
- });
- },
-
- /**
- * Sets the state of PropertyEditor widgets when edit mode begins or ends.
- *
- * Should be called whenever EditAppModel's "isViewing" changes.
- */
- appStateChange: function() {
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133, https://github.com/bergie/create/issues/140)
- // We're currently setting the state on EditableEntity widgets instead of
- // PropertyEditor widgets, because of
- // https://github.com/bergie/create/issues/133.
- var newState = (this.model.get('isViewing')) ? 'inactive' : 'candidate';
- this.$entityElements.each(function() {
- $(this).createEditable('setState', newState);
- });
- // Manage the page's tab indexes.
- if (newState === 'candidate') {
- this._manageDocumentFocus();
- Drupal.edit.setMessage(Drupal.t('In place edit mode is active'), Drupal.t('Page navigation is limited to editable items.'), Drupal.t('Press escape to exit'));
- }
- else if (newState === 'inactive') {
- this._releaseDocumentFocusManagement();
- Drupal.edit.setMessage(Drupal.t('Edit mode is inactive.'), Drupal.t('Resume normal page navigation'));
- }
- },
-
- /**
- * Accepts or reject editor (PropertyEditor) state changes.
- *
- * This is what ensures that the app is in control of what happens.
- *
- * @param from
- * The previous state.
- * @param to
- * The new state.
- * @param predicate
- * The predicate of the property for which the state change is happening.
- * @param context
- * The context that is trying to trigger the state change.
- * @param callback
- * The callback function that should receive the state acceptance result.
- */
- acceptEditorStateChange: function(from, to, predicate, context, callback) {
- var accept = true;
-
- // If the app is in view mode, then reject all state changes except for
- // those to 'inactive'.
- if (this.model.get('isViewing')) {
- if (to !== 'inactive') {
- accept = false;
- }
- }
- // Handling of edit mode state changes is more granular.
- else {
- // In general, enforce the states sequence. Disallow going back from a
- // "later" state to an "earlier" state, except in explicitly allowed
- // cases.
- if (_.indexOf(this.states, from) > _.indexOf(this.states, to)) {
- accept = false;
- // Allow: activating/active -> candidate.
- // Necessary to stop editing a property.
- if (_.indexOf(this.activeEditorStates, from) !== -1 && to === 'candidate') {
- accept = true;
- }
- // Allow: changed/invalid -> candidate.
- // Necessary to stop editing a property when it is changed or invalid.
- else if ((from === 'changed' || from === 'invalid') && to === 'candidate') {
- accept = true;
- }
- // Allow: highlighted -> candidate.
- // Necessary to stop highlighting a property.
- else if (from === 'highlighted' && to === 'candidate') {
- accept = true;
- }
- // Allow: saved -> candidate.
- // Necessary when successfully saved a property.
- else if (from === 'saved' && to === 'candidate') {
- accept = true;
- }
- // Allow: invalid -> saving.
- // Necessary to be able to save a corrected, invalid property.
- else if (from === 'invalid' && to === 'saving') {
- accept = true;
- }
- }
-
- // If it's not against the general principle, then here are more
- // disallowed cases to check.
- if (accept) {
- // Ensure only one editor (field) at a time may be higlighted or active.
- if (from === 'candidate' && _.indexOf(this.singleEditorStates, to) !== -1) {
- if (this.model.get('highlightedEditor') || this.model.get('activeEditor')) {
- accept = false;
- }
- }
- // Reject going from activating/active to candidate because of a
- // mouseleave.
- else if (_.indexOf(this.activeEditorStates, from) !== -1 && to === 'candidate') {
- if (context && context.reason === 'mouseleave') {
- accept = false;
- }
- }
- // When attempting to stop editing a changed/invalid property, ask for
- // confirmation.
- else if ((from === 'changed' || from === 'invalid') && to === 'candidate') {
- if (context && context.reason === 'mouseleave') {
- accept = false;
- }
- else {
- // Check whether the transition has been confirmed?
- if (context && context.confirmed) {
- accept = true;
- }
- // Confirm this transition.
- else {
- // The callback will be called from the helper function.
- this._confirmStopEditing(callback);
- return;
- }
- }
- }
- }
- }
-
- callback(accept);
- },
-
- /**
- * Asks the user to confirm whether he wants to stop editing via a modal.
- *
- * @param acceptCallback
- * The callback function as passed to acceptEditorStateChange(). This
- * callback function will be called with the user's choice.
- *
- * @see acceptEditorStateChange()
- */
- _confirmStopEditing: function(acceptCallback) {
- // Only instantiate if there isn't a modal instance visible yet.
- if (!this.model.get('activeModal')) {
- var that = this;
- var modal = new Drupal.edit.views.ModalView({
- model: this.model,
- message: Drupal.t('You have unsaved changes'),
- buttons: [
- { action: 'discard', classes: 'gray-button', label: Drupal.t('Discard changes') },
- { action: 'save', type: 'submit', classes: 'blue-button', label: Drupal.t('Save') }
- ],
- callback: function(action) {
- // The active modal has been removed.
- that.model.set('activeModal', null);
- if (action === 'discard') {
- acceptCallback(true);
- }
- else {
- acceptCallback(false);
- var editor = that.model.get('activeEditor');
- editor.options.widget.setState('saving', editor.options.property);
- }
- }
- });
- this.model.set('activeModal', modal);
- // The modal will set the activeModal property on the model when rendering
- // to prevent multiple modals from being instantiated.
- modal.render();
- }
- else {
- // Reject as there is still an open transition waiting for confirmation.
- acceptCallback(false);
- }
- },
-
- /**
- * Reacts to editor (PropertyEditor) state changes; tracks global state.
- *
- * @param from
- * The previous state.
- * @param to
- * The new state.
- * @param editor
- * The PropertyEditor widget object.
- */
- editorStateChange: function(from, to, editor) {
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133)
- // Get rid of this once that issue is solved.
- if (!editor) {
- return;
- }
- else {
- editor.stateChange(from, to);
- }
-
- // Keep track of the highlighted editor in the global state.
- if (_.indexOf(this.singleEditorStates, to) !== -1 && this.model.get('highlightedEditor') !== editor) {
- this.model.set('highlightedEditor', editor);
- }
- else if (this.model.get('highlightedEditor') === editor && to === 'candidate') {
- this.model.set('highlightedEditor', null);
- }
-
- // Keep track of the active editor in the global state.
- if (_.indexOf(this.activeEditorStates, to) !== -1 && this.model.get('activeEditor') !== editor) {
- this.model.set('activeEditor', editor);
- Drupal.edit.setMessage(Drupal.t('An editor is active'));
- }
- else if (this.model.get('activeEditor') === editor && to === 'candidate') {
- // Discarded if it transitions from a changed state to 'candidate'.
- if (from === 'changed' || from === 'invalid') {
- // Retrieve the storage widget from DOM.
- var createStorageWidget = this.$el.data('createStorage');
- // Revert changes in the model, this will trigger the direct editable
- // content to be reset and redrawn.
- createStorageWidget.revertChanges(editor.options.entity);
- }
- this.model.set('activeEditor', null);
- }
-
- // Propagate the state change to the decoration and toolbar views.
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133)
- // Uncomment this once that issue is solved.
- // editor.decorationView.stateChange(from, to);
- // editor.toolbarView.stateChange(from, to);
- },
-
- /**
- * Decorates an editor (PropertyEditor).
- *
- * Upon the page load, all appropriate editors are initialized and decorated
- * (i.e. even before anything of the editing UI becomes visible; even before
- * edit mode is enabled).
- *
- * @param editor
- * The PropertyEditor widget object.
- */
- decorateEditor: function(editor) {
- // Toolbars are rendered "on-demand" (highlighting or activating).
- // They are a sibling element before the editor's DOM element.
- editor.toolbarView = new Drupal.edit.views.ToolbarView({
- editor: editor,
- $storageWidgetEl: this.$el
- });
-
- // Decorate the editor's DOM element depending on its state.
- editor.decorationView = new Drupal.edit.views.PropertyEditorDecorationView({
- el: editor.element,
- editor: editor,
- toolbarId: editor.toolbarView.getId()
- });
-
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133)
- // Get rid of this once that issue is solved.
- editor.options.widget.element.on('createeditablestatechange', function(event, data) {
- editor.decorationView.stateChange(data.previous, data.current);
- editor.toolbarView.stateChange(data.previous, data.current);
- });
- },
-
- /**
- * Undecorates an editor (PropertyEditor).
- *
- * Whenever a property has been updated, the old HTML will be replaced by
- * the new (re-rendered) HTML. The EditableEntity widget will be destroyed,
- * as will be the PropertyEditor widget. This method ensures Edit's editor
- * views also are removed properly.
- *
- * @param editor
- * The PropertyEditor widget object.
- */
- undecorateEditor: function(editor) {
- editor.toolbarView.undelegateEvents();
- editor.toolbarView.remove();
- delete editor.toolbarView;
- editor.decorationView.undelegateEvents();
- // Don't call .remove() on the decoration view, because that would remove
- // a potentially rerendered field.
- delete editor.decorationView;
- },
-
- /**
- * Makes elements other than the editables unreachable via the tab key.
- *
- * @todo refactoring.
- *
- * This method is currently overloaded, handling elements of state modeling
- * and application control. The state of the application is spread between
- * this view, its model and aspects of the UI widgets in Create.js. In order
- * to drive focus management from the application state (and have it
- * influence that state of the application), we need to distall state out
- * of Create.js components.
- *
- * This method introduces behaviors that support accessibility of the edit
- * application. Although not yet integrated into the application properly,
- * it does provide us with the opportunity to collect feedback from
- * users who will interact with edit primarily through keyboard input. We
- * want this feedback sooner than we can have a refactored application.
- */
- _manageDocumentFocus: function () {
- var editablesSelector = '.edit-candidate.edit-editable';
- var inputsSelector = 'a:visible, button:visible, input:visible, textarea:visible, select:visible';
- var $editables = $(editablesSelector)
- .attr({
- 'tabindex': 0,
- 'role': 'button'
- });
- // Instantiate a variable to hold the editable element in the set.
- var $currentEditable;
- // We're using simple function scope to manage 'this' for the internal
- // handler, so save this as that.
- var that = this;
- // Turn on focus management.
- $(document).on('keydown.edit', function (event) {
- var activeEditor, editableEntity, predicate;
- // Handle esc key press. Close any active editors.
- if (event.keyCode === 27) {
- event.preventDefault();
- activeEditor = that.model.get('activeEditor');
- if (activeEditor) {
- editableEntity = activeEditor.options.widget;
- predicate = activeEditor.options.property;
- editableEntity.setState('candidate', predicate, { reason: 'overlay' });
- }
- else {
- $(editablesSelector).trigger('tabOut.edit');
- // This should move into the state management for the app model.
- location.hash = "#view";
- that.model.set('isViewing', true);
- }
- return;
- }
- // Handle enter or space key presses.
- if (event.keyCode === 13 || event.keyCode === 32) {
- if ($currentEditable && $currentEditable.is(editablesSelector)) {
- $currentEditable.trigger('click');
- // Squelch additional handlers.
- event.preventDefault();
- return;
- }
- }
- // Handle tab key presses.
- if (event.keyCode === 9) {
- var context = '';
- // Include the view mode toggle with the editables selector.
- var selector = editablesSelector + ', #toolbar-tab-edit';
- activeEditor = that.model.get('activeEditor');
- var $confirmDialog = $('#edit_modal');
- // If the edit modal is active, that is the tabbing context.
- if ($confirmDialog.length) {
- context = $confirmDialog;
- selector = inputsSelector;
- if (!$currentEditable || $currentEditable.is(editablesSelector)) {
- $currentEditable = $(selector, context).eq(-1);
- }
- }
- // If an editor is active, then the tabbing context is the editor and
- // its toolbar.
- else if (activeEditor) {
- context = $(activeEditor.$formContainer).add(activeEditor.toolbarView.$el);
- // Include the view mode toggle with the editables selector.
- selector = inputsSelector;
- if (!$currentEditable || $currentEditable.is(editablesSelector)) {
- $currentEditable = $(selector, context).eq(-1);
- }
- }
- // Otherwise the tabbing context is the list of editable predicates.
- var $editables = $(selector, context);
- if (!$currentEditable) {
- $currentEditable = $editables.eq(-1);
- }
- var count = $editables.length - 1;
- var index = $editables.index($currentEditable);
- // Navigate backwards.
- if (event.shiftKey) {
- // Beginning of the set, loop to the end.
- if (index === 0) {
- index = count;
- }
- else {
- index -= 1;
- }
- }
- // Navigate forewards.
- else {
- // End of the set, loop to the start.
- if (index === count) {
- index = 0;
- }
- else {
- index += 1;
- }
- }
- // Tab out of the current editable.
- $currentEditable.trigger('tabOut.edit');
- // Update the current editable.
- $currentEditable = $editables
- .eq(index)
- .focus()
- .trigger('tabIn.edit');
- // Squelch additional handlers.
- event.preventDefault();
- event.stopPropagation();
- }
- });
- // Set focus on the edit button initially.
- $('#toolbar-tab-edit').focus();
- },
- /**
- * Removes key management and edit accessibility features from the DOM.
- */
- _releaseDocumentFocusManagement: function () {
- $(document).off('keydown.edit');
- $('.edit-allowed.edit-field').removeAttr('tabindex role');
- }
- });
-
-})(jQuery, _, Backbone, Drupal, VIE);
diff --git a/core/modules/edit/js/backbone.drupalform.js b/core/modules/edit/js/backbone.drupalform.js
deleted file mode 100644
index ba79e76..0000000
--- a/core/modules/edit/js/backbone.drupalform.js
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * @file
- * Backbone.sync implementation for Edit. This is the beating heart.
- */
-(function (jQuery, Backbone, Drupal) {
-
-"use strict";
-
-Backbone.defaultSync = Backbone.sync;
-Backbone.sync = function(method, model, options) {
- if (options.editor.options.editorName === 'form') {
- return Backbone.syncDrupalFormWidget(method, model, options);
- }
- else {
- return Backbone.syncDirect(method, model, options);
- }
-};
-
-/**
- * Performs syncing for "form" PredicateEditor widgets.
- *
- * Implemented on top of Form API and the AJAX commands framework. Sets up
- * scoped AJAX command closures specifically for a given PredicateEditor widget
- * (which contains a pre-existing form). By submitting the form through
- * Drupal.ajax and leveraging Drupal.ajax' ability to have scoped (per-instance)
- * command implementations, we are able to update the VIE model, re-render the
- * form when there are validation errors and ensure no Drupal.ajax memory leaks.
- *
- * @see Drupal.edit.util.form
- */
-Backbone.syncDrupalFormWidget = function(method, model, options) {
- if (method === 'update') {
- var predicate = options.editor.options.property;
-
- var $formContainer = options.editor.$formContainer;
- var $submit = $formContainer.find('.edit-form-submit');
- var base = $submit.attr('id');
-
- // Successfully saved.
- Drupal.ajax[base].commands.editFieldFormSaved = function(ajax, response, status) {
- Drupal.edit.util.form.unajaxifySaving(jQuery(ajax.element));
-
- // Call Backbone.sync's success callback with the rerendered field.
- var changedAttributes = {};
- // @todo: POSTPONED_ON(Drupal core, http://drupal.org/node/1784216)
- // Once full JSON-LD support in Drupal core lands, we can ensure that the
- // models that VIE maintains are properly updated.
- changedAttributes[predicate] = undefined;
- changedAttributes[predicate + '/rendered'] = response.data;
- options.success(changedAttributes);
- };
-
- // Unsuccessfully saved; validation errors.
- Drupal.ajax[base].commands.editFieldFormValidationErrors = function(ajax, response, status) {
- // Call Backbone.sync's error callback with the validation error messages.
- options.error(response.data);
- };
-
- // The edit_field_form AJAX command is only called upon loading the form for
- // the first time, and when there are validation errors in the form; Form
- // API then marks which form items have errors. Therefor, we have to replace
- // the existing form, unbind the existing Drupal.ajax instance and create a
- // new Drupal.ajax instance.
- Drupal.ajax[base].commands.editFieldForm = function(ajax, response, status) {
- Drupal.edit.util.form.unajaxifySaving(jQuery(ajax.element));
-
- Drupal.ajax.prototype.commands.insert(ajax, {
- data: response.data,
- selector: '#' + $formContainer.attr('id') + ' form'
- });
-
- // Create a Drupa.ajax instance for the re-rendered ("new") form.
- var $newSubmit = $formContainer.find('.edit-form-submit');
- Drupal.edit.util.form.ajaxifySaving({ nocssjs: false }, $newSubmit);
- };
-
- // Click the form's submit button; the scoped AJAX commands above will
- // handle the server's response.
- $submit.trigger('click.edit');
- }
-};
-
-/**
-* Performs syncing for "direct" PredicateEditor widgets.
- *
- * @see Backbone.syncDrupalFormWidget()
- * @see Drupal.edit.util.form
- */
-Backbone.syncDirect = function(method, model, options) {
- if (method === 'update') {
- var fillAndSubmitForm = function(value) {
- jQuery('#edit_backstage form')
- // Fill in the value in any that isn't hidden or a submit button.
- .find(':input[type!="hidden"][type!="submit"]:not(select)').val(value).end()
- // Submit the form.
- .find('.edit-form-submit').trigger('click.edit');
- };
- var entity = options.editor.options.entity;
- var predicate = options.editor.options.property;
- var value = model.get(predicate);
-
- // If form doesn't already exist, load it and then submit.
- if (jQuery('#edit_backstage form').length === 0) {
- var formOptions = {
- propertyID: Drupal.edit.util.calcPropertyID(entity, predicate),
- $editorElement: options.editor.element,
- nocssjs: true
- };
- Drupal.edit.util.form.load(formOptions, function(form, ajax) {
- // Create a backstage area for storing forms that are hidden from view
- // (hence "backstage" — since the editing doesn't happen in the form, it
- // happens "directly" in the content, the form is only used for saving).
- jQuery(Drupal.theme('editBackstage', { id: 'edit_backstage' })).appendTo('body');
- // Direct forms are stuffed into #edit_backstage, apparently.
- jQuery('#edit_backstage').append(form);
- // Disable the browser's HTML5 validation; we only care about server-
- // side validation. (Not disabling this will actually cause problems
- // because browsers don't like to set HTML5 validation errors on hidden
- // forms.)
- jQuery('#edit_backstage form').attr('novalidate', true);
- var $submit = jQuery('#edit_backstage form .edit-form-submit');
- var base = Drupal.edit.util.form.ajaxifySaving(formOptions, $submit);
-
- // Successfully saved.
- Drupal.ajax[base].commands.editFieldFormSaved = function (ajax, response, status) {
- Drupal.edit.util.form.unajaxifySaving(jQuery(ajax.element));
- jQuery('#edit_backstage form').remove();
-
- // Call Backbone.sync's success callback with the rerendered field.
- var changedAttributes = {};
- // @todo: POSTPONED_ON(Drupal core, http://drupal.org/node/1784216)
- // Once full JSON-LD support in Drupal core lands, we can ensure that the
- // models that VIE maintains are properly updated.
- changedAttributes[predicate] = jQuery(response.data).find('.field-item').html();
- changedAttributes[predicate + '/rendered'] = response.data;
- options.success(changedAttributes);
- };
-
- // Unsuccessfully saved; validation errors.
- Drupal.ajax[base].commands.editFieldFormValidationErrors = function(ajax, response, status) {
- // Call Backbone.sync's error callback with the validation error messages.
- options.error(response.data);
- };
-
- // The editFieldForm AJAX command is only called upon loading the form
- // for the first time, and when there are validation errors in the form;
- // Form API then marks which form items have errors. This is useful for
- // "form" editors, but pointless for "direct" editors: the form itself
- // won't be visible at all anyway! Therefor, we ignore the new form and
- // we continue to use the existing form.
- Drupal.ajax[base].commands.editFieldForm = function(ajax, response, status) {
- // no-op
- };
-
- fillAndSubmitForm(value);
- });
- }
- else {
- fillAndSubmitForm(value);
- }
- }
-};
-
-})(jQuery, Backbone, Drupal);
diff --git a/core/modules/edit/js/createjs/editable.js b/core/modules/edit/js/createjs/editable.js
deleted file mode 100644
index aac1ed2..0000000
--- a/core/modules/edit/js/createjs/editable.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file
- * Determines which editor to use based on a class attribute.
- */
-(function (jQuery, drupalSettings) {
-
-"use strict";
-
- jQuery.widget('Drupal.createEditable', jQuery.Midgard.midgardEditable, {
- _create: function() {
- this.vie = this.options.vie;
-
- this.options.domService = 'edit';
- this.options.predicateSelector = '*'; //'.edit-field.edit-allowed';
-
- this.options.editors.direct = {
- widget: 'drupalContentEditableWidget',
- options: {}
- };
- this.options.editors['direct-with-wysiwyg'] = {
- widget: drupalSettings.edit.wysiwygEditorWidgetName,
- options: {}
- };
- this.options.editors.form = {
- widget: 'drupalFormWidget',
- options: {}
- };
-
- jQuery.Midgard.midgardEditable.prototype._create.call(this);
- },
-
- _propertyEditorName: function(data) {
- if (jQuery(this.element).hasClass('edit-type-direct')) {
- if (jQuery(this.element).hasClass('edit-type-direct-with-wysiwyg')) {
- return 'direct-with-wysiwyg';
- }
- return 'direct';
- }
- return 'form';
- }
- });
-
-})(jQuery, drupalSettings);
diff --git a/core/modules/edit/js/createjs/editingWidgets/drupalcontenteditablewidget.js b/core/modules/edit/js/createjs/editingWidgets/drupalcontenteditablewidget.js
deleted file mode 100644
index c773e6e..0000000
--- a/core/modules/edit/js/createjs/editingWidgets/drupalcontenteditablewidget.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @file
- * Override of Create.js' default "base" (plain contentEditable) widget.
- */
-(function (jQuery, Drupal) {
-
-"use strict";
-
- jQuery.widget('Drupal.drupalContentEditableWidget', jQuery.Create.editWidget, {
-
- /**
- * Implements jQuery UI widget factory's _init() method.
- *
- * @todo: POSTPONED_ON(Create.js, https://github.com/bergie/create/issues/142)
- * Get rid of this once that issue is solved.
- */
- _init: function() {},
-
- /**
- * Implements Create's _initialize() method.
- */
- _initialize: function() {
- var that = this;
-
- // Sets the state to 'activated' upon clicking the element.
- this.element.on("click.edit", function(event) {
- event.stopPropagation();
- event.preventDefault();
- that.options.activated();
- });
-
- // Sets the state to 'changed' whenever the content has changed.
- var before = jQuery.trim(this.element.text());
- this.element.on('keyup paste', function (event) {
- if (that.options.disabled) {
- return;
- }
- var current = jQuery.trim(that.element.text());
- if (before !== current) {
- before = current;
- that.options.changed(current);
- }
- });
- },
-
- /**
- * Makes this PropertyEditor widget react to state changes.
- */
- stateChange: function(from, to) {
- switch (to) {
- case 'inactive':
- break;
- case 'candidate':
- if (from !== 'inactive') {
- // Removes the "contenteditable" attribute.
- this.disable();
- this._removeValidationErrors();
- this._cleanUp();
- }
- break;
- case 'highlighted':
- break;
- case 'activating':
- break;
- case 'active':
- // Sets the "contenteditable" attribute to "true".
- this.enable();
- break;
- case 'changed':
- break;
- case 'saving':
- this._removeValidationErrors();
- break;
- case 'saved':
- break;
- case 'invalid':
- break;
- }
- },
-
- /**
- * Removes validation errors' markup changes, if any.
- *
- * Note: this only needs to happen for type=direct, because for type=direct,
- * the property DOM element itself is modified; this is not the case for
- * type=form.
- */
- _removeValidationErrors: function() {
- this.element
- .removeClass('edit-validation-error')
- .next('.edit-validation-errors').remove();
- },
-
- /**
- * Cleans up after the widget has been saved.
- *
- * Note: this is where the Create.Storage and accompanying Backbone.sync
- * abstractions "leak" implementation details. That is only the case because
- * we have to use Drupal's Form API as a transport mechanism. It is
- * unfortunately a stateful transport mechanism, and that's why we have to
- * clean it up here. This clean-up is only necessary when canceling the
- * editing of a property after having attempted to save at least once.
- */
- _cleanUp: function() {
- Drupal.edit.util.form.unajaxifySaving(jQuery('#edit_backstage form .edit-form-submit'));
- jQuery('#edit_backstage form').remove();
- }
- });
-
-})(jQuery, Drupal);
diff --git a/core/modules/edit/js/createjs/editingWidgets/formwidget.js b/core/modules/edit/js/createjs/editingWidgets/formwidget.js
deleted file mode 100644
index f7c77cd..0000000
--- a/core/modules/edit/js/createjs/editingWidgets/formwidget.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @file
- * Form-based Create.js widget for structured content in Drupal.
- */
-(function ($, Drupal) {
-
-"use strict";
-
- $.widget('Drupal.drupalFormWidget', $.Create.editWidget, {
-
- id: null,
- $formContainer: null,
-
- /**
- * Implements jQuery UI widget factory's _init() method.
- *
- * @todo: POSTPONED_ON(Create.js, https://github.com/bergie/create/issues/142)
- * Get rid of this once that issue is solved.
- */
- _init: function() {},
-
- /**
- * Implements Create's _initialize() method.
- */
- _initialize: function() {
- // Sets the state to 'activating' upon clicking the element.
- var that = this;
- this.element.on("click.edit", function(event) {
- event.stopPropagation();
- event.preventDefault();
- that.options.activating();
- });
- },
-
- /**
- * Makes this PropertyEditor widget react to state changes.
- */
- stateChange: function(from, to) {
- switch (to) {
- case 'inactive':
- break;
- case 'candidate':
- if (from !== 'inactive') {
- this.disable();
- }
- break;
- case 'highlighted':
- break;
- case 'activating':
- this.enable();
- break;
- case 'active':
- break;
- case 'changed':
- break;
- case 'saving':
- break;
- case 'saved':
- break;
- case 'invalid':
- break;
- }
- },
-
- /**
- * Enables the widget.
- */
- enable: function () {
- var $editorElement = $(this.options.widget.element);
- var propertyID = Drupal.edit.util.calcPropertyID(this.options.entity, this.options.property);
-
- // Generate a DOM-compatible ID for the form container DOM element.
- this.id = 'edit-form-for-' + propertyID.replace(/\//g, '_');
-
- // Render form container.
- this.$formContainer = $(Drupal.theme('editFormContainer', {
- id: this.id,
- loadingMsg: Drupal.t('Loading…')}
- ));
- this.$formContainer
- .find('.edit-form')
- .addClass('edit-editable edit-highlighted edit-editing')
- .attr('role', 'dialog')
- .css('background-color', $editorElement.css('background-color'));
-
- // Insert form container in DOM.
- if ($editorElement.css('display') === 'inline') {
- // @todo: POSTPONED_ON(Drupal core, title/author/date as Entity Properties)
- // This is untested in Drupal 8, because in Drupal 8 we don't yet
- // have the ability to edit the node title/author/date, because they
- // haven't been converted into Entity Properties yet, and they're the
- // only examples in core of "display: inline" properties.
- this.$formContainer.prependTo($editorElement.offsetParent());
-
- var pos = $editorElement.position();
- this.$formContainer.css('left', pos.left).css('top', pos.top);
- }
- else {
- this.$formContainer.insertBefore($editorElement);
- }
-
- // Load form, insert it into the form container and attach event handlers.
- var widget = this;
- var formOptions = {
- propertyID: propertyID,
- $editorElement: $editorElement,
- nocssjs: false
- };
- Drupal.edit.util.form.load(formOptions, function(form, ajax) {
- Drupal.ajax.prototype.commands.insert(ajax, {
- data: form,
- selector: '#' + widget.id + ' .placeholder'
- });
-
- var $submit = widget.$formContainer.find('.edit-form-submit');
- Drupal.edit.util.form.ajaxifySaving(formOptions, $submit);
- widget.$formContainer
- .on('formUpdated.edit', ':input', function () {
- // Sets the state to 'changed'.
- widget.options.changed();
- })
- .on('keypress.edit', 'input', function (event) {
- if (event.keyCode === 13) {
- return false;
- }
- });
-
- // Sets the state to 'activated'.
- widget.options.activated();
- });
- },
-
- /**
- * Disables the widget.
- */
- disable: function () {
- if (this.$formContainer === null) {
- return;
- }
-
- Drupal.edit.util.form.unajaxifySaving(this.$formContainer.find('.edit-form-submit'));
- this.$formContainer
- .off('change.edit', ':input')
- .off('keypress.edit', 'input')
- .remove();
- this.$formContainer = null;
- }
- });
-
-})(jQuery, Drupal);
diff --git a/core/modules/edit/js/createjs/storage.js b/core/modules/edit/js/createjs/storage.js
deleted file mode 100644
index 580ff82..0000000
--- a/core/modules/edit/js/createjs/storage.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @file
- * Subclasses jQuery.Midgard.midgardStorage to have consistent namespaces.
- */
-(function(jQuery) {
-
-"use strict";
-
- jQuery.widget('Drupal.createStorage', jQuery.Midgard.midgardStorage, {});
-
-})(jQuery);
diff --git a/core/modules/edit/js/edit.js b/core/modules/edit/js/edit.js
deleted file mode 100644
index 41a7f49..0000000
--- a/core/modules/edit/js/edit.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file
- * Behaviors for Edit, including the one that initializes Edit's EditAppView.
- */
-(function ($, _, Backbone, Drupal, drupalSettings) {
-
-"use strict";
-
-/**
- * The edit ARIA live message area.
- *
- * @todo Eventually the messages area should be converted into a Backbone View
- * that will respond to changes in the application's model. For the initial
- * implementation, we will call the Drupal.edit.setMessage method when an aural
- * message should be read by the user agent.
- */
-var $messages;
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.metadataCache = Drupal.edit.metadataCache || {};
-
-/**
- * Attach toggling behavior and in-place editing.
- */
-Drupal.behaviors.edit = {
- attach: function(context) {
- var $context = $(context);
- var $fields = $context.find('[data-edit-id]');
-
- // Initialize the Edit app.
- $context.find('#toolbar-tab-edit').once('edit-init', Drupal.edit.init);
-
- var annotateField = function(field) {
- if (_.has(Drupal.edit.metadataCache, field.editID)) {
- var meta = Drupal.edit.metadataCache[field.editID];
-
- field.$el.addClass((meta.access) ? 'edit-allowed' : 'edit-disallowed');
- if (meta.access) {
- field.$el
- .attr('data-edit-field-label', meta.label)
- .attr('aria-label', meta.aria)
- .addClass('edit-field edit-type-' + meta.editor);
- if (meta.editor === 'direct-with-wysiwyg') {
- field.$el
- // This editor also uses the Backbone.syncDirect saving mechanism.
- .addClass('edit-type-direct')
- .attr('data-edit-text-format', meta.format)
- .addClass((meta.formatHasTransformations) ? 'edit-text-with-transformation-filters' : 'edit-text-without-transformation-filters');
- }
- }
-
- return true;
- }
- return false;
- };
-
- // Find all fields in the context without metadata.
- var fieldsToAnnotate = _.map($fields.not('.edit-allowed, .edit-disallowed'), function(el) {
- var $el = $(el);
- return { $el: $el, editID: $el.attr('data-edit-id') };
- });
-
- // Fields whose metadata is known (typically when they were just modified)
- // can be annotated immediately, those remaining must be requested.
- var remainingFieldsToAnnotate = _.reduce(fieldsToAnnotate, function(result, field) {
- if (!annotateField(field)) {
- result.push(field);
- }
- return result;
- }, []);
-
- // Make fields that could be annotated immediately available for editing.
- Drupal.edit.app.findEditableProperties($context);
-
- if (remainingFieldsToAnnotate.length) {
- $(window).ready(function() {
- $.ajax({
- url: drupalSettings.edit.metadataURL,
- type: 'POST',
- data: { 'fields[]' : _.pluck(remainingFieldsToAnnotate, 'editID') },
- dataType: 'json',
- success: function(results) {
- // Update the metadata cache.
- _.each(results, function(metadata, editID) {
- Drupal.edit.metadataCache[editID] = metadata;
- });
-
- // Annotate the remaining fields based on the updated access cache.
- _.each(remainingFieldsToAnnotate, annotateField);
-
- // As soon as there is at least one editable field, show the Edit
- // tab in the toolbar.
- if ($fields.filter('.edit-allowed').length) {
- $('.toolbar .icon-edit.edit-nothing-editable-hidden')
- .removeClass('edit-nothing-editable-hidden');
- }
-
- // Find editable fields, make them editable.
- Drupal.edit.app.findEditableProperties($context);
- }
- });
- });
- }
- }
-};
-
-Drupal.edit.init = function() {
- // Append a messages element for appending interaction updates for screen
- // readers.
- $messages = $(Drupal.theme('editMessageBox')).appendTo($(this).parent());
- // Instantiate EditAppView, which is the controller of it all. EditAppModel
- // instance tracks global state (viewing/editing in-place).
- var appModel = new Drupal.edit.models.EditAppModel();
- var app = new Drupal.edit.EditAppView({
- el: $('body'),
- model: appModel
- });
-
- // Instantiate EditRouter.
- var editRouter = new Drupal.edit.routers.EditRouter({
- appModel: appModel
- });
-
- // Start Backbone's history/route handling.
- Backbone.history.start();
-
- // For now, we work with a singleton app, because for Drupal.behaviors to be
- // able to discover new editable properties that get AJAXed in, it must know
- // with which app instance they should be associated.
- Drupal.edit.app = app;
-};
-
-/**
- * Places the message in the edit ARIA live message area.
- *
- * The message will be read by speaking User Agents.
- *
- * @param {String} message
- * A string to be inserted into the message area.
- */
-Drupal.edit.setMessage = function(message) {
- var args = Array.prototype.slice.call(arguments);
- args.unshift('editMessage');
- $messages.html(Drupal.theme.apply(this, args));
-};
-
-})(jQuery, _, Backbone, Drupal, drupalSettings);
diff --git a/core/modules/edit/js/models/edit-app-model.js b/core/modules/edit/js/models/edit-app-model.js
deleted file mode 100644
index b6ff36f..0000000
--- a/core/modules/edit/js/models/edit-app-model.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * @file
- * A Backbone Model that models the current Edit application state.
- */
-(function(Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.models = Drupal.edit.models || {};
-Drupal.edit.models.EditAppModel = Backbone.Model.extend({
- defaults: {
- // We always begin in view mode.
- isViewing: true,
- highlightedEditor: null,
- activeEditor: null,
- // Reference to a ModalView-instance if a transition requires confirmation.
- activeModal: null
- }
-});
-
-})(Backbone, Drupal);
diff --git a/core/modules/edit/js/routers/edit-router.js b/core/modules/edit/js/routers/edit-router.js
deleted file mode 100644
index d160ad4..0000000
--- a/core/modules/edit/js/routers/edit-router.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file
- * A Backbone Router enabling URLs to make the user enter edit mode directly.
- */
-(function(Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.routers = {};
-Drupal.edit.routers.EditRouter = Backbone.Router.extend({
-
- appModel: null,
-
- routes: {
- "edit": "edit",
- "view": "view",
- "": "view"
- },
-
- initialize: function(options) {
- this.appModel = options.appModel;
-
- var that = this;
- this.appModel.on('change:isViewing', function() {
- that.navigate(that.appModel.get('isViewing') ? '#view' : '#edit');
- });
- },
-
- edit: function() {
- this.appModel.set('isViewing', false);
- },
-
- view: function(query, page) {
- var that = this;
-
- // If there's an active editor, attempt to set its state to 'candidate', and
- // then act according to the user's choice.
- var activeEditor = this.appModel.get('activeEditor');
- if (activeEditor) {
- var editableEntity = activeEditor.options.widget;
- var predicate = activeEditor.options.property;
- editableEntity.setState('candidate', predicate, { reason: 'menu' }, function(accepted) {
- if (accepted) {
- that.appModel.set('isViewing', true);
- }
- else {
- that.appModel.set('isViewing', false);
- }
- });
- }
- // Otherwise, we can switch to view mode directly.
- else {
- that.appModel.set('isViewing', true);
- }
- }
-});
-
-})(Backbone, Drupal);
diff --git a/core/modules/edit/js/theme.js b/core/modules/edit/js/theme.js
deleted file mode 100644
index 80dcbef..0000000
--- a/core/modules/edit/js/theme.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @file
- * Provides overridable theme functions for all of Edit's client-side HTML.
- */
-(function($, Drupal) {
-
-"use strict";
-
-/**
- * Theme function for the overlay of the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - None.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editOverlay = function(settings) {
- var html = '';
- html += '
';
- return html;
-};
-
-/**
- * Theme function for a "backstage" for the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - id: the id to apply to the backstage.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editBackstage = function(settings) {
- var html = '';
- html += '';
- return html;
-};
-
-/**
- * Theme function for a modal of the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - None.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editModal = function(settings) {
- var classes = 'edit-animate-slow edit-animate-invisible edit-animate-delay-veryfast';
- var html = '';
- html += '
';
- html += '
';
- html += ' ';
- html += '
';
- return html;
-};
-
-/**
- * Theme function for a toolbar container of the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - id: the id to apply to the toolbar container.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editToolbarContainer = function(settings) {
- var html = '';
- html += '
';
- html += '
';
- html += ' ';
- html += '
';
- html += '
';
- return html;
-};
-
-/**
- * Theme function for a toolbar toolgroup of the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - classes: the class of the toolgroup.
- * - buttons: @see Drupal.theme.prototype.editButtons().
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editToolgroup = function(settings) {
- var classes = 'edit-toolgroup edit-animate-slow edit-animate-invisible edit-animate-delay-veryfast';
- var html = '';
- html += '
';
- html += Drupal.theme('editButtons', { buttons: settings.buttons });
- html += '
';
- return html;
-};
-
-/**
- * Theme function for buttons of the Edit module.
- *
- * Can be used for the buttons both in the toolbar toolgroups and in the modal.
- *
- * @param settings
- * An object with the following keys:
- * - buttons: an array of objects with the following keys:
- * - type: the type of the button (defaults to 'button')
- * - classes: the classes of the button.
- * - label: the label of the button.
- * - action: sets a data-edit-modal-action attribute.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editButtons = function(settings) {
- var html = '';
- for (var i = 0; i < settings.buttons.length; i++) {
- var button = settings.buttons[i];
- if (!button.hasOwnProperty('type')) {
- button.type = 'button';
- }
-
- html += '';
- }
- return html;
-};
-
-/**
- * Theme function for a form container of the Edit module.
- *
- * @param settings
- * An object with the following keys:
- * - id: the id to apply to the toolbar container.
- * - loadingMsg: The message to show while loading.
- * @return
- * The corresponding HTML.
- */
-Drupal.theme.editFormContainer = function(settings) {
- var html = '';
- html += '
';
- html += '
';
- html += '
';
- html += settings.loadingMsg;
- html += '
';
- html += '
';
- html += '
';
- return html;
-};
-
-/**
- * A region to post messages that a screen reading UA will announce.
- *
- * @return {String}
- * A string representing a DOM fragment.
- */
-Drupal.theme.editMessageBox = function() {
- return '';
-};
-
-/**
- * Wrap message strings in p tags.
- *
- * @return {String}
- * A string representing a DOM fragment.
- */
-Drupal.theme.editMessage = function() {
- var messages = Array.prototype.slice.call(arguments);
- var output = '';
- for (var i = 0; i < messages.length; i++) {
- output += '
' + messages[i] + '
';
- }
- return output;
-};
-
-})(jQuery, Drupal);
diff --git a/core/modules/edit/js/util.js b/core/modules/edit/js/util.js
deleted file mode 100644
index 8ed9a2b..0000000
--- a/core/modules/edit/js/util.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * @file
- * Provides utility functions for Edit.
- */
-(function($, Drupal, drupalSettings) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.util = Drupal.edit.util || {};
-
-Drupal.edit.util.constants = {};
-Drupal.edit.util.constants.transitionEnd = "transitionEnd.edit webkitTransitionEnd.edit transitionend.edit msTransitionEnd.edit oTransitionEnd.edit";
-
-Drupal.edit.util.calcPropertyID = function(entity, predicate) {
- return entity.getSubjectUri() + '/' + predicate;
-};
-
-Drupal.edit.util.buildUrl = function(id, urlFormat) {
- var parts = id.split('/');
- return Drupal.formatString(decodeURIComponent(urlFormat), {
- '!entity_type': parts[0],
- '!id' : parts[1],
- '!field_name' : parts[2],
- '!langcode' : parts[3],
- '!view_mode' : parts[4]
- });
-};
-
-/**
- * Loads rerendered processed text for a given property.
- *
- * Leverages Drupal.ajax' ability to have scoped (per-instance) command
- * implementations to be able to call a callback.
- *
- * @param options
- * An object with the following keys:
- * - $editorElement (required): the PredicateEditor DOM element.
- * - propertyID (required): the property ID that uniquely identifies the
- * property for which this form will be loaded.
- * - callback (required: A callback function that will receive the rerendered
- * processed text.
- */
-Drupal.edit.util.loadRerenderedProcessedText = function(options) {
- // Create a Drupal.ajax instance to load the form.
- Drupal.ajax[options.propertyID] = new Drupal.ajax(options.propertyID, options.$editorElement, {
- url: Drupal.edit.util.buildUrl(options.propertyID, drupalSettings.edit.rerenderProcessedTextURL),
- event: 'edit-internal.edit',
- submit: { nocssjs : true },
- progress: { type : null } // No progress indicator.
- });
- // Implement a scoped editFieldRenderedWithoutTransformationFilters AJAX
- // command: calls the callback.
- Drupal.ajax[options.propertyID].commands.editFieldRenderedWithoutTransformationFilters = function(ajax, response, status) {
- options.callback(response.data);
- // Delete the Drupal.ajax instance that called this very function.
- delete Drupal.ajax[options.propertyID];
- options.$editorElement.off('edit-internal.edit');
- };
- // This will ensure our scoped editFieldRenderedWithoutTransformationFilters
- // AJAX command gets called.
- options.$editorElement.trigger('edit-internal.edit');
-};
-
-Drupal.edit.util.form = {
- /**
- * Loads a form, calls a callback to inserts.
- *
- * Leverages Drupal.ajax' ability to have scoped (per-instance) command
- * implementations to be able to call a callback.
- *
- * @param options
- * An object with the following keys:
- * - $editorElement (required): the PredicateEditor DOM element.
- * - propertyID (required): the property ID that uniquely identifies the
- * property for which this form will be loaded.
- * - nocssjs (required): boolean indicating whether no CSS and JS should be
- * returned (necessary when the form is invisible to the user).
- * @param callback
- * A callback function that will receive the form to be inserted, as well as
- * the ajax object, necessary if the callback wants to perform other AJAX
- * commands.
- */
- load: function(options, callback) {
- // Create a Drupal.ajax instance to load the form.
- Drupal.ajax[options.propertyID] = new Drupal.ajax(options.propertyID, options.$editorElement, {
- url: Drupal.edit.util.buildUrl(options.propertyID, drupalSettings.edit.fieldFormURL),
- event: 'edit-internal.edit',
- submit: { nocssjs : options.nocssjs },
- progress: { type : null } // No progress indicator.
- });
- // Implement a scoped editFieldForm AJAX command: calls the callback.
- Drupal.ajax[options.propertyID].commands.editFieldForm = function(ajax, response, status) {
- callback(response.data, ajax);
- // Delete the Drupal.ajax instance that called this very function.
- delete Drupal.ajax[options.propertyID];
- options.$editorElement.off('edit-internal.edit');
- };
- // This will ensure our scoped editFieldForm AJAX command gets called.
- options.$editorElement.trigger('edit-internal.edit');
- },
-
- /**
- * Creates a Drupal.ajax instance that is used to save a form.
- *
- * @param options
- * An object with the following keys:
- * - nocssjs (required): boolean indicating whether no CSS and JS should be
- * returned (necessary when the form is invisible to the user).
- *
- * @return
- * The key of the Drupal.ajax instance.
- */
- ajaxifySaving: function(options, $submit) {
- // Re-wire the form to handle submit.
- var element_settings = {
- url: $submit.closest('form').attr('action'),
- setClick: true,
- event: 'click.edit',
- progress: { type:'throbber' },
- submit: { nocssjs : options.nocssjs }
- };
- var base = $submit.attr('id');
-
- Drupal.ajax[base] = new Drupal.ajax(base, $submit[0], element_settings);
-
- return base;
- },
-
- /**
- * Cleans up the Drupal.ajax instance that is used to save the form.
- *
- * @param $submit
- * The jQuery-wrapped submit DOM element that should be unajaxified.
- */
- unajaxifySaving: function($submit) {
- delete Drupal.ajax[$submit.attr('id')];
- $submit.off('click.edit');
- }
-};
-
-})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/edit/js/viejs/EditService.js b/core/modules/edit/js/viejs/EditService.js
deleted file mode 100644
index f52a6c0..0000000
--- a/core/modules/edit/js/viejs/EditService.js
+++ /dev/null
@@ -1,297 +0,0 @@
-/**
- * @file
- * VIE DOM parsing service for Edit.
- */
-(function(jQuery, _, VIE, Drupal, drupalSettings) {
-
-"use strict";
-
- VIE.prototype.EditService = function (options) {
- var defaults = {
- name: 'edit',
- subjectSelector: '.edit-field.edit-allowed'
- };
- this.options = _.extend({}, defaults, options);
-
- this.views = [];
- this.vie = null;
- this.name = this.options.name;
- };
-
- VIE.prototype.EditService.prototype = {
- load: function (loadable) {
- var correct = loadable instanceof this.vie.Loadable;
- if (!correct) {
- throw new Error('Invalid Loadable passed');
- }
-
- var element;
- if (!loadable.options.element) {
- if (typeof document === 'undefined') {
- return loadable.resolve([]);
- } else {
- element = drupalSettings.edit.context;
- }
- } else {
- element = loadable.options.element;
- }
-
- var entities = this.readEntities(element);
- loadable.resolve(entities);
- },
-
- _getViewForElement:function (element, collectionView) {
- var viewInstance;
-
- jQuery.each(this.views, function () {
- if (jQuery(this.el).get(0) === element.get(0)) {
- if (collectionView && !this.template) {
- return true;
- }
- viewInstance = this;
- return false;
- }
- });
- return viewInstance;
- },
-
- _registerEntityView:function (entity, element, isNew) {
- if (!element.length) {
- return;
- }
-
- // Let's only have this overhead for direct types. Form-based editors are
- // handled in backbone.drupalform.js and the PropertyEditor instance.
- if (!jQuery(element).hasClass('edit-type-direct')) {
- return;
- }
-
- var service = this;
- var viewInstance = this._getViewForElement(element);
- if (viewInstance) {
- return viewInstance;
- }
-
- viewInstance = new this.vie.view.Entity({
- model:entity,
- el:element,
- tagName:element.get(0).nodeName,
- vie:this.vie,
- service:this.name
- });
-
- this.views.push(viewInstance);
-
- return viewInstance;
- },
-
- save: function(saveable) {
- var correct = saveable instanceof this.vie.Savable;
- if (!correct) {
- throw "Invalid Savable passed";
- }
-
- if (!saveable.options.element) {
- // FIXME: we could find element based on subject
- throw "Unable to write entity to edit.module-markup, no element given";
- }
-
- if (!saveable.options.entity) {
- throw "Unable to write to edit.module-markup, no entity given";
- }
-
- var $element = jQuery(saveable.options.element);
- this._writeEntity(saveable.options.entity, saveable.options.element);
- saveable.resolve();
- },
-
- _writeEntity:function (entity, element) {
- var service = this;
- this.findPredicateElements(this.getElementSubject(element), element, true).each(function () {
- var predicateElement = jQuery(this);
- var predicate = service.getElementPredicate(predicateElement);
- if (!entity.has(predicate)) {
- return true;
- }
-
- var value = entity.get(predicate);
- if (value && value.isCollection) {
- // Handled by CollectionViews separately
- return true;
- }
- if (value === service.readElementValue(predicate, predicateElement)) {
- return true;
- }
- // Unlike in the VIE's RdfaService no (re-)mapping needed here.
- predicateElement.html(value);
- });
- return true;
- },
-
- // The edit-id data attribute contains the full identifier of
- // each entity element in the format
- // `::::`.
- _getID: function (element) {
- var id = jQuery(element).attr('data-edit-id');
- if (!id) {
- id = jQuery(element).closest('[data-edit-id]').attr('data-edit-id');
- }
- return id;
- },
-
- // Returns the "URI" of an entity of an element in format
- // `/`.
- getElementSubject: function (element) {
- return this._getID(element).split(':').slice(0, 2).join('/');
- },
-
- // Returns the field name for an element in format
- // `//`.
- // (Slashes instead of colons because the field name is no namespace.)
- getElementPredicate: function (element) {
- if (!this._getID(element)) {
- throw new Error('Could not find predicate for element');
- }
- return this._getID(element).split(':').slice(2, 5).join('/');
- },
-
- getElementType: function (element) {
- return this._getID(element).split(':').slice(0, 1)[0];
- },
-
- // Reads all editable entities (currently each Drupal field is considered an
- // entity, in the future Drupal entities should be mapped to VIE entities)
- // from DOM and returns the VIE enties it found.
- readEntities: function (element) {
- var service = this;
- var entities = [];
- var entityElements = jQuery(this.options.subjectSelector, element);
- entityElements = entityElements.add(jQuery(element).filter(this.options.subjectSelector));
- entityElements.each(function () {
- var entity = service._readEntity(jQuery(this));
- if (entity) {
- entities.push(entity);
- }
- });
- return entities;
- },
-
- // Returns a filled VIE Entity instance for a DOM element. The Entity
- // is also registered in the VIE entities collection.
- _readEntity: function (element) {
- var subject = this.getElementSubject(element);
- var type = this.getElementType(element);
- var entity = this._readEntityPredicates(subject, element, false);
- if (jQuery.isEmptyObject(entity)) {
- return null;
- }
- entity['@subject'] = subject;
- if (type) {
- entity['@type'] = this._registerType(type, element);
- }
-
- var entityInstance = new this.vie.Entity(entity);
- entityInstance = this.vie.entities.addOrUpdate(entityInstance, {
- updateOptions: {
- silent: true,
- ignoreChanges: true
- }
- });
-
- this._registerEntityView(entityInstance, element);
- return entityInstance;
- },
-
- _registerType: function (typeId, element) {
- typeId = '';
- var type = this.vie.types.get(typeId);
- if (!type) {
- this.vie.types.add(typeId, []);
- type = this.vie.types.get(typeId);
- }
-
- var predicate = this.getElementPredicate(element);
- if (type.attributes.get(predicate)) {
- return type;
- }
-
- var label = element.data('edit-field-label');
- var range = 'Form';
- if (element.hasClass('edit-type-direct')) {
- range = 'Direct';
- }
- if (element.hasClass('edit-type-direct-with-wysiwyg')) {
- range = 'Wysiwyg';
- }
- type.attributes.add(predicate, [range], 0, 1, {
- label: element.data('edit-field-label')
- });
-
- return type;
- },
-
- _readEntityPredicates: function (subject, element, emptyValues) {
- var entityPredicates = {};
- var service = this;
- this.findPredicateElements(subject, element, true).each(function () {
- var predicateElement = jQuery(this);
- var predicate = service.getElementPredicate(predicateElement);
- if (!predicate) {
- return;
- }
- var value = service.readElementValue(predicate, predicateElement);
- if (value === null && !emptyValues) {
- return;
- }
-
- entityPredicates[predicate] = value;
- entityPredicates[predicate + '/rendered'] = predicateElement[0].outerHTML;
- });
- return entityPredicates;
- },
-
- readElementValue : function(predicate, element) {
- // Unlike in RdfaService there is parsing needed here.
- if (element.hasClass('edit-type-form')) {
- return undefined;
- }
- else {
- return jQuery.trim(element.html());
- }
- },
-
- // Subject elements are the DOM elements containing a single or multiple
- // editable fields.
- findSubjectElements: function (element) {
- if (!element) {
- element = drupalSettings.edit.context;
- }
- return jQuery(this.options.subjectSelector, element);
- },
-
- // Predicate Elements are the actual DOM elements that users will be able
- // to edit.
- findPredicateElements: function (subject, element, allowNestedPredicates, stop) {
- var predicates = jQuery();
- // Make sure that element is wrapped by jQuery.
- var $element = jQuery(element);
-
- // Form-type predicates
- predicates = predicates.add($element.filter('.edit-type-form'));
-
- // Direct-type predicates
- var direct = $element.filter('.edit-type-direct');
- predicates = predicates.add(direct.find('.field-item'));
-
- if (!predicates.length && !stop) {
- var parentElement = $element.parent(this.options.subjectSelector);
- if (parentElement.length) {
- return this.findPredicateElements(subject, parentElement, allowNestedPredicates, true);
- }
- }
-
- return predicates;
- }
- };
-
-})(jQuery, _, VIE, Drupal, drupalSettings);
diff --git a/core/modules/edit/js/views/menu-view.js b/core/modules/edit/js/views/menu-view.js
deleted file mode 100644
index ac7c4e4..0000000
--- a/core/modules/edit/js/views/menu-view.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file
- * A Backbone View that provides the app-level interactive menu.
- */
-(function($, _, Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.views = Drupal.edit.views || {};
-Drupal.edit.views.MenuView = Backbone.View.extend({
-
- events: {
- 'click #toolbar-tab-edit': 'editClickHandler'
- },
-
- /**
- * Implements Backbone Views' initialize() function.
- */
- initialize: function() {
- _.bindAll(this, 'stateChange');
- this.model.on('change:isViewing', this.stateChange);
- // @todo
- // Re-implement hook_toolbar and the corresponding JavaScript behaviors
- // once https://drupal.org/node/1847198 is resolved. The toolbar tray is
- // necessary when the page request is processed because its render element
- // has an #attached property with the Edit module library code assigned to
- // it. Currently a toolbar tab is not passed as a renderable array, so
- // #attached properties are not processed. The toolbar tray DOM element is
- // unnecessary right now, so it is removed.
- this.$el.find('#toolbar-tray-edit').remove();
- // Respond to clicks on other toolbar tabs. This temporary pending
- // improvements to the toolbar module.
- $('#toolbar-administration').on('click.edit', '.bar a:not(#toolbar-tab-edit)', _.bind(function (event) {
- this.model.set('isViewing', true);
- }, this));
- // We have to call stateChange() here because URL fragments are not passed
- // to the server, thus the wrong anchor may be marked as active.
- this.stateChange();
- },
-
- /**
- * Listens to app state changes.
- */
- stateChange: function() {
- var isViewing = this.model.get('isViewing');
- // Toggle the state of the Toolbar Edit tab based on the isViewing state.
- this.$el.find('#toolbar-tab-edit')
- .toggleClass('active', !isViewing)
- .attr('aria-pressed', !isViewing);
- // Manage the toolbar state until
- // https://drupal.org/node/1847198 is resolved
- if (!isViewing) {
- // Remove the 'toolbar-tray-open' class from the body element.
- this.$el.removeClass('toolbar-tray-open');
- // Deactivate any other active tabs and trays.
- this.$el
- .find('.bar a', '#toolbar-administration')
- .not('#toolbar-tab-edit')
- .add('.tray', '#toolbar-administration')
- .removeClass('active');
- // Set the height of the toolbar.
- if ('toolbar' in Drupal) {
- Drupal.toolbar.setHeight();
- }
- }
- },
- /**
- * Handles clicks on the edit tab of the toolbar.
- *
- * @param {Object} event
- */
- editClickHandler: function (event) {
- var isViewing = this.model.get('isViewing');
- // Toggle the href of the Toolbar Edit tab based on the isViewing state. The
- // href value should represent to state to be entered.
- this.$el.find('#toolbar-tab-edit').attr('href', (isViewing) ? '#edit' : '#view');
- this.model.set('isViewing', !isViewing);
- }
-});
-
-})(jQuery, _, Backbone, Drupal);
diff --git a/core/modules/edit/js/views/modal-view.js b/core/modules/edit/js/views/modal-view.js
deleted file mode 100644
index 2e3b49c..0000000
--- a/core/modules/edit/js/views/modal-view.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file
- * A Backbone View that provides an interactive modal.
- */
-(function($, Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.views = Drupal.edit.views || {};
-Drupal.edit.views.ModalView = Backbone.View.extend({
-
- message: null,
- buttons: null,
- callback: null,
- $elementsToHide: null,
-
- events: {
- 'click button': 'onButtonClick'
- },
-
- /**
- * Implements Backbone Views' initialize() function.
- *
- * @param options
- * An object with the following keys:
- * - message: a message to show in the modal.
- * - buttons: a set of buttons with 'action's defined, ready to be passed to
- * Drupal.theme.editButtons().
- * - callback: a callback that will receive the 'action' of the clicked
- * button.
- *
- * @see Drupal.theme.editModal()
- * @see Drupal.theme.editButtons()
- */
- initialize: function(options) {
- this.message = options.message;
- this.buttons = options.buttons;
- this.callback = options.callback;
- },
-
- /**
- * Implements Backbone Views' render() function.
- */
- render: function() {
- // Step 1: move certain UI elements below the overlay.
- var editor = this.model.get('activeEditor');
- this.$elementsToHide = $([])
- .add((editor.element.hasClass('edit-belowoverlay')) ? null : editor.element)
- .add(editor.toolbarView.$el)
- .add((editor.options.editorName === 'form') ? editor.$formContainer : editor.element.next('.edit-validation-errors'));
- this.$elementsToHide.addClass('edit-belowoverlay');
-
- // Step 2: the modal. When the user makes a choice, the UI elements that
- // were moved below the overlay will be restored, and the callback will be
- // called.
- this.setElement(Drupal.theme('editModal', {}));
- this.$el.appendTo('body');
- // Template.
- this.$('.main p').text(this.message);
- var $actions = $(Drupal.theme('editButtons', { 'buttons' : this.buttons}));
- this.$('.actions').append($actions);
-
- // Step 3; show the modal with an animation.
- var that = this;
- setTimeout(function() {
- that.$el.removeClass('edit-animate-invisible');
- }, 0);
-
- Drupal.edit.setMessage(Drupal.t('Confirmation dialog open'));
- },
-
- /**
- * When the user clicks on any of the buttons, the modal should be removed
- * and the result should be passed to the callback.
- *
- * @param event
- */
- onButtonClick: function(event) {
- event.stopPropagation();
- event.preventDefault();
-
- // Remove after animation.
- var that = this;
- this.$el
- .addClass('edit-animate-invisible')
- .on(Drupal.edit.util.constants.transitionEnd, function(e) {
- that.remove();
- });
-
- var action = $(event.target).attr('data-edit-modal-action');
- return this.callback(action);
- },
-
- /**
- * Overrides Backbone Views' remove() function.
- */
- remove: function() {
- // Move the moved UI elements on top of the overlay again.
- this.$elementsToHide.removeClass('edit-belowoverlay');
-
- // Remove the modal itself.
- this.$el.remove();
- }
-});
-
-})(jQuery, Backbone, Drupal);
diff --git a/core/modules/edit/js/views/overlay-view.js b/core/modules/edit/js/views/overlay-view.js
deleted file mode 100644
index 2113ab8..0000000
--- a/core/modules/edit/js/views/overlay-view.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file
- * A Backbone View that provides the app-level overlay.
- *
- * The overlay sits on top of the existing content, the properties that are
- * candidates for editing sit on top of the overlay.
- */
-(function ($, _, Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.views = Drupal.edit.views || {};
-Drupal.edit.views.OverlayView = Backbone.View.extend({
-
- events: {
- 'click': 'onClick'
- },
-
- /**
- * Implements Backbone Views' initialize() function.
- */
- initialize: function (options) {
- _.bindAll(this, 'stateChange');
- this.model.on('change:isViewing', this.stateChange);
- // Add the overlay to the page.
- this.$el
- .addClass('edit-animate-slow edit-animate-invisible')
- .hide()
- .appendTo('body');
- },
-
- /**
- * Listens to app state changes.
- */
- stateChange: function () {
- if (this.model.get('isViewing')) {
- this.remove();
- return;
- }
- this.render();
- },
-
- /**
- * Equates clicks anywhere on the overlay to clicking the active editor's (if
- * any) "close" button.
- *
- * @param {Object} event
- */
- onClick: function (event) {
- event.preventDefault();
- var activeEditor = this.model.get('activeEditor');
- if (activeEditor) {
- var editableEntity = activeEditor.options.widget;
- var predicate = activeEditor.options.property;
- editableEntity.setState('candidate', predicate, { reason: 'overlay' });
- }
- else {
- this.model.set('isViewing', true);
- }
- },
-
- /**
- * Reveal the overlay element.
- */
- render: function () {
- this.$el
- .show()
- .css('top', $('#navbar').outerHeight())
- .removeClass('edit-animate-invisible');
- },
-
- /**
- * Hide the overlay element.
- */
- remove: function () {
- var that = this;
- this.$el
- .addClass('edit-animate-invisible')
- .on(Drupal.edit.util.constants.transitionEnd, function (event) {
- that.$el.hide();
- });
- }
-});
-
-})(jQuery, _, Backbone, Drupal);
diff --git a/core/modules/edit/js/views/propertyeditordecoration-view.js b/core/modules/edit/js/views/propertyeditordecoration-view.js
deleted file mode 100644
index 269259a..0000000
--- a/core/modules/edit/js/views/propertyeditordecoration-view.js
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * @file
- * A Backbone View that decorates a Property Editor widget.
- *
- * It listens to state changes of the property editor.
- */
-(function($, Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.views = Drupal.edit.views || {};
-Drupal.edit.views.PropertyEditorDecorationView = Backbone.View.extend({
-
- editor: null,
- entity: null,
- predicate : null,
- editorName: null,
- toolbarId: null,
-
- _widthAttributeIsEmpty: null,
-
- events: {
- 'mouseenter.edit' : 'onMouseEnter',
- 'mouseleave.edit' : 'onMouseLeave',
- 'tabIn.edit': 'onMouseEnter',
- 'tabOut.edit': 'onMouseLeave'
- },
-
- /**
- * Implements Backbone Views' initialize() function.
- *
- * @param options
- * An object with the following keys:
- * - editor: the editor object with an 'options' object that has these keys:
- * * entity: the VIE entity for the property.
- * * property: the predicate of the property.
- * * editorName: the editor name: 'form', 'direct' or
- * 'direct-with-wysiwyg'.
- * * widget: the parent EditableeEntity widget.
- * - toolbarId: the ID attribute of the toolbar as rendered in the DOM.
- */
- initialize: function(options) {
- this.editor = options.editor;
- this.toolbarId = options.toolbarId;
-
- this.entity = this.editor.options.entity;
- this.predicate = this.editor.options.property;
- this.editorName = this.editor.options.editorName;
-
- this.$el.css('background-color', this._getBgColor(this.$el));
- },
-
- /**
- * Listens to editor state changes.
- */
- stateChange: function(from, to) {
- switch (to) {
- case 'inactive':
- if (from !== null) {
- this.undecorate();
- }
- break;
- case 'candidate':
- this.decorate();
- if (from !== 'inactive') {
- this.stopHighlight();
- if (from !== 'highlighted') {
- this.stopEdit(this.editorName);
- }
- }
- break;
- case 'highlighted':
- this.startHighlight();
- break;
- case 'activating':
- // NOTE: this step only exists for the 'form' editor! It is skipped by
- // the 'direct' and 'direct-with-wysiwyg' editors, because no loading is
- // necessary.
- this.prepareEdit(this.editorName);
- break;
- case 'active':
- if (this.editorName !== 'form') {
- this.prepareEdit(this.editorName);
- }
- this.startEdit(this.editorName);
- break;
- case 'changed':
- break;
- case 'saving':
- break;
- case 'saved':
- break;
- case 'invalid':
- break;
- }
- },
-
- /**
- * Starts hover: transition to 'highlight' state.
- *
- * @param event
- */
- onMouseEnter: function(event) {
- var that = this;
- this._ignoreHoveringVia(event, '#' + this.toolbarId, function () {
- var editableEntity = that.editor.options.widget;
- editableEntity.setState('highlighted', that.predicate);
- event.stopPropagation();
- });
- },
-
- /**
- * Stops hover: back to 'candidate' state.
- *
- * @param event
- */
- onMouseLeave: function(event) {
- var that = this;
- this._ignoreHoveringVia(event, '#' + this.toolbarId, function () {
- var editableEntity = that.editor.options.widget;
- editableEntity.setState('candidate', that.predicate, { reason: 'mouseleave' });
- event.stopPropagation();
- });
- },
-
- decorate: function () {
- this.$el.addClass('edit-animate-fast edit-candidate edit-editable');
- },
-
- undecorate: function () {
- this.$el
- .removeClass('edit-candidate edit-editable edit-highlighted edit-editing edit-belowoverlay');
- },
-
- startHighlight: function () {
- // Animations.
- var that = this;
- setTimeout(function() {
- that.$el.addClass('edit-highlighted');
- }, 0);
- },
-
- stopHighlight: function() {
- this.$el
- .removeClass('edit-highlighted');
- },
-
- prepareEdit: function(editorName) {
- this.$el.addClass('edit-editing');
-
- // While editing, don't show *any* other editors.
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133)
- // Revisit this.
- $('.edit-candidate').not('.edit-editing').removeClass('edit-editable');
-
- if (editorName === 'form') {
- this.$el.addClass('edit-belowoverlay');
- }
- },
-
- startEdit: function(editorName) {
- if (editorName !== 'form') {
- this._pad();
- }
- },
-
- stopEdit: function(editorName) {
- this.$el.removeClass('edit-highlighted edit-editing');
-
- // Make the other editors show up again.
- // @todo: BLOCKED_ON(Create.js, https://github.com/bergie/create/issues/133)
- // Revisit this.
- $('.edit-candidate').addClass('edit-editable');
-
- if (editorName === 'form') {
- this.$el.removeClass('edit-belowoverlay');
- }
- else {
- this._unpad();
- }
- },
-
- _pad: function () {
- var self = this;
-
- // Add 5px padding for readability. This means we'll freeze the current
- // width and *then* add 5px padding, hence ensuring the padding is added "on
- // the outside".
- // 1) Freeze the width (if it's not already set); don't use animations.
- if (this.$el[0].style.width === "") {
- this._widthAttributeIsEmpty = true;
- this.$el
- .addClass('edit-animate-disable-width')
- .css('width', this.$el.width());
- }
-
- // 2) Add padding; use animations.
- var posProp = this._getPositionProperties(this.$el);
- setTimeout(function() {
- // Re-enable width animations (padding changes affect width too!).
- self.$el.removeClass('edit-animate-disable-width');
-
- // Pad the editable.
- self.$el
- .css({
- 'position': 'relative',
- 'top': posProp.top - 5 + 'px',
- 'left': posProp.left - 5 + 'px',
- 'padding-top' : posProp['padding-top'] + 5 + 'px',
- 'padding-left' : posProp['padding-left'] + 5 + 'px',
- 'padding-right' : posProp['padding-right'] + 5 + 'px',
- 'padding-bottom': posProp['padding-bottom'] + 5 + 'px',
- 'margin-bottom': posProp['margin-bottom'] - 10 + 'px'
- });
- }, 0);
- },
-
- _unpad: function () {
- var self = this;
-
- // 1) Set the empty width again.
- if (this._widthAttributeIsEmpty) {
- this.$el
- .addClass('edit-animate-disable-width')
- .css('width', '');
- }
-
- // 2) Remove padding; use animations (these will run simultaneously with)
- // the fading out of the toolbar as its gets removed).
- var posProp = this._getPositionProperties(this.$el);
- setTimeout(function() {
- // Re-enable width animations (padding changes affect width too!).
- self.$el.removeClass('edit-animate-disable-width');
-
- // Unpad the editable.
- self.$el
- .css({
- 'position': 'relative',
- 'top': posProp.top + 5 + 'px',
- 'left': posProp.left + 5 + 'px',
- 'padding-top' : posProp['padding-top'] - 5 + 'px',
- 'padding-left' : posProp['padding-left'] - 5 + 'px',
- 'padding-right' : posProp['padding-right'] - 5 + 'px',
- 'padding-bottom': posProp['padding-bottom'] - 5 + 'px',
- 'margin-bottom': posProp['margin-bottom'] + 10 + 'px'
- });
- }, 0);
- },
-
- /**
- * Gets the background color of an element (or the inherited one).
- *
- * @param $e
- * A DOM element.
- */
- _getBgColor: function($e) {
- var c;
-
- if ($e === null || $e[0].nodeName === 'HTML') {
- // Fallback to white.
- return 'rgb(255, 255, 255)';
- }
- c = $e.css('background-color');
- // TRICKY: edge case for Firefox' "transparent" here; this is a
- // browser bug: https://bugzilla.mozilla.org/show_bug.cgi?id=635724
- if (c === 'rgba(0, 0, 0, 0)' || c === 'transparent') {
- return this._getBgColor($e.parent());
- }
- return c;
- },
-
- /**
- * Gets the top and left properties of an element and convert extraneous
- * values and information into numbers ready for subtraction.
- *
- * @param $e
- * A DOM element.
- */
- _getPositionProperties: function($e) {
- var p,
- r = {},
- props = [
- 'top', 'left', 'bottom', 'right',
- 'padding-top', 'padding-left', 'padding-right', 'padding-bottom',
- 'margin-bottom'
- ];
-
- var propCount = props.length;
- for (var i = 0; i < propCount; i++) {
- p = props[i];
- r[p] = parseInt(this._replaceBlankPosition($e.css(p)), 10);
- }
- return r;
- },
-
- /**
- * Replaces blank or 'auto' CSS "position: " values with "0px".
- *
- * @param pos
- * The value for a CSS position declaration.
- */
- _replaceBlankPosition: function(pos) {
- if (pos === 'auto' || !pos) {
- pos = '0px';
- }
- return pos;
- },
-
- /**
- * Ignores hovering to/from the given closest element, but as soon as a hover
- * occurs to/from *another* element, then call the given callback.
- */
- _ignoreHoveringVia: function(event, closest, callback) {
- if ($(event.relatedTarget).closest(closest).length > 0) {
- event.stopPropagation();
- }
- else {
- callback();
- }
- }
-});
-
-})(jQuery, Backbone, Drupal);
diff --git a/core/modules/edit/js/views/toolbar-view.js b/core/modules/edit/js/views/toolbar-view.js
deleted file mode 100644
index 899b9e3..0000000
--- a/core/modules/edit/js/views/toolbar-view.js
+++ /dev/null
@@ -1,465 +0,0 @@
-/**
- * @file
- * A Backbone View that provides an interactive toolbar (1 per property editor).
- *
- * It listens to state changes of the property editor. It also triggers state
- * changes in response to user interactions with the toolbar, including saving.
- */
-(function ($, _, Backbone, Drupal) {
-
-"use strict";
-
-Drupal.edit = Drupal.edit || {};
-Drupal.edit.views = Drupal.edit.views || {};
-Drupal.edit.views.ToolbarView = Backbone.View.extend({
-
- editor: null,
- $storageWidgetEl: null,
-
- entity: null,
- predicate : null,
- editorName: null,
-
- _loader: null,
- _loaderVisibleStart: 0,
-
- _id: null,
-
- events: {
- 'click.edit button.label': 'onClickInfoLabel',
- 'mouseleave.edit': 'onMouseLeave',
- 'click.edit button.field-save': 'onClickSave',
- 'click.edit button.field-close': 'onClickClose'
- },
-
- /**
- * Implements Backbone Views' initialize() function.
- *
- * @param options
- * An object with the following keys:
- * - editor: the editor object with an 'options' object that has these keys:
- * * entity: the VIE entity for the property.
- * * property: the predicate of the property.
- * * editorName: the editor name: 'form', 'direct' or
- * 'direct-with-wysiwyg'.
- * * element: the jQuery-wrapped editor DOM element
- * - $storageWidgetEl: the DOM element on which the Create Storage widget is
- * initialized.
- */
- initialize: function(options) {
- this.editor = options.editor;
- this.$storageWidgetEl = options.$storageWidgetEl;
-
- this.entity = this.editor.options.entity;
- this.predicate = this.editor.options.property;
- this.editorName = this.editor.options.editorName;
-
- this._loader = null;
- this._loaderVisibleStart = 0;
-
- // Generate a DOM-compatible ID for the toolbar DOM element.
- var propertyID = Drupal.edit.util.calcPropertyID(this.entity, this.predicate);
- this._id = 'edit-toolbar-for-' + propertyID.replace(/\//g, '_');
- },
-
- /**
- * Listens to editor state changes.
- */
- stateChange: function(from, to) {
- switch (to) {
- case 'inactive':
- // Nothing happens in this stage.
- break;
- case 'candidate':
- if (from !== 'inactive') {
- if (from !== 'highlighted' && this.editorName !== 'form') {
- this._unpad(this.editorName);
- }
- this.remove();
- }
- break;
- case 'highlighted':
- // As soon as we highlight, make sure we have a toolbar in the DOM (with at least a title).
- this.render();
- this.startHighlight();
- break;
- case 'activating':
- this.setLoadingIndicator(true);
- break;
- case 'active':
- this.startEdit(this.editorName);
- this.setLoadingIndicator(false);
- if (this.editorName !== 'form') {
- this._pad(this.editorName);
- }
- if (this.editorName === 'direct-with-wysiwyg') {
- this.insertWYSIWYGToolGroups();
- }
- break;
- case 'changed':
- this.$el
- .find('button.save')
- .addClass('blue-button')
- .removeClass('gray-button');
- break;
- case 'saving':
- this.setLoadingIndicator(true);
- this.save();
- break;
- case 'saved':
- this.setLoadingIndicator(false);
- break;
- case 'invalid':
- this.setLoadingIndicator(false);
- break;
- }
- },
-
- /**
- * Saves a property.
- *
- * This method deals with the complexity of the editor-dependent ways of
- * inserting updated content and showing validation error messages.
- *
- * One might argue that this does not belong in a view. However, there is no
- * actual "save" logic here, that lives in Backbone.sync. This is just some
- * glue code, along with the logic for inserting updated content as well as
- * showing validation error messages, the latter of which is certainly okay.
- */
- save: function() {
- var that = this;
- var editor = this.editor;
- var editableEntity = editor.options.widget;
- var entity = editor.options.entity;
- var predicate = editor.options.property;
-
- // Use Create.js' Storage widget to handle saving. (Uses Backbone.sync.)
- this.$storageWidgetEl.createStorage('saveRemote', entity, {
- editor: editor,
-
- // Successfully saved without validation errors.
- success: function (model) {
- editableEntity.setState('saved', predicate);
-
- // Now that the changes to this property have been saved, the saved
- // attributes are now the "original" attributes.
- entity._originalAttributes = entity._previousAttributes = _.clone(entity.attributes);
-
- // Get data necessary to rerender property before it is unavailable.
- var updatedProperty = entity.get(predicate + '/rendered');
- var $propertyWrapper = editor.element.closest('.edit-field');
- var $context = $propertyWrapper.parent();
-
- editableEntity.setState('candidate', predicate);
- // Unset the property, because it will be parsed again from the DOM, iff
- // its new value causes it to still be rendered.
- entity.unset(predicate, { silent: true });
- entity.unset(predicate + '/rendered', { silent: true });
- // Trigger event to allow for proper clean-up of editor-specific views.
- editor.element.trigger('destroyedPropertyEditor.edit', editor);
-
- // Replace the old content with the new content.
- $propertyWrapper.replaceWith(updatedProperty);
- Drupal.attachBehaviors($context);
- },
-
- // Save attempted but failed due to validation errors.
- error: function (validationErrorMessages) {
- editableEntity.setState('invalid', predicate);
-
- if (that.editorName === 'form') {
- editor.$formContainer
- .find('.edit-form')
- .addClass('edit-validation-error')
- .find('form')
- .prepend(validationErrorMessages);
- }
- else {
- var $errors = $('')
- .append(validationErrorMessages);
- editor.element
- .addClass('edit-validation-error')
- .after($errors);
- }
- }
- });
- },
-
- /**
- * When the user clicks the info label, nothing should happen.
- * @note currently redirects the click.edit-event to the editor DOM element.
- *
- * @param event
- */
- onClickInfoLabel: function(event) {
- event.stopPropagation();
- event.preventDefault();
- // Redirects the event to the editor DOM element.
- this.editor.element.trigger('click.edit');
- },
-
- /**
- * A mouseleave to the editor doesn't matter; a mouseleave to something else
- * counts as a mouseleave on the editor itself.
- *
- * @param event
- */
- onMouseLeave: function(event) {
- var el = this.editor.element[0];
- if (event.relatedTarget != el && !$.contains(el, event.relatedTarget)) {
- this.editor.element.trigger('mouseleave.edit');
- }
- event.stopPropagation();
- },
-
- /**
- * Upon clicking "Save", trigger a custom event to save this property.
- *
- * @param event
- */
- onClickSave: function(event) {
- event.stopPropagation();
- event.preventDefault();
- this.editor.options.widget.setState('saving', this.predicate);
- },
-
- /**
- * Upon clicking "Close", trigger a custom event to stop editing.
- *
- * @param event
- */
- onClickClose: function(event) {
- event.stopPropagation();
- event.preventDefault();
- this.editor.options.widget.setState('candidate', this.predicate, { reason: 'cancel' });
- },
-
- /**
- * Indicates in the 'info' toolgroup that we're waiting for a server reponse.
- *
- * Prevents flickering loading indicator by only showing it after 0.6 seconds
- * and if it is shown, only hiding it after another 0.6 seconds.
- *
- * @param bool enabled
- * Whether the loading indicator should be displayed or not.
- */
- setLoadingIndicator: function(enabled) {
- var that = this;
- if (enabled) {
- this._loader = setTimeout(function() {
- that.addClass('info', 'loading');
- that._loaderVisibleStart = new Date().getTime();
- }, 600);
- }
- else {
- var currentTime = new Date().getTime();
- clearTimeout(this._loader);
- if (this._loaderVisibleStart) {
- setTimeout(function() {
- that.removeClass('info', 'loading');
- }, this._loaderVisibleStart + 600 - currentTime);
- }
- this._loader = null;
- this._loaderVisibleStart = 0;
- }
- },
-
- startHighlight: function() {
- // We get the label to show for this property from VIE's type system.
- var label = this.predicate;
- var attributeDef = this.entity.get('@type').attributes.get(this.predicate);
- if (attributeDef && attributeDef.metadata) {
- label = attributeDef.metadata.label;
- }
-
- this.$el
- .find('.edit-toolbar')
- // Append the "info" toolgroup into the toolbar.
- .append(Drupal.theme('editToolgroup', {
- classes: 'info edit-animate-only-background-and-padding',
- buttons: [
- { label: label, classes: 'blank-button label' }
- ]
- }));
-
- // Animations.
- var that = this;
- setTimeout(function () {
- that.show('info');
- }, 0);
- },
-
- startEdit: function() {
- this.$el
- .addClass('edit-editing')
- .find('.edit-toolbar')
- // Append the "ops" toolgroup into the toolbar.
- .append(Drupal.theme('editToolgroup', {
- classes: 'ops',
- buttons: [
- { label: Drupal.t('Save'), type: 'submit', classes: 'field-save save gray-button' },
- { label: '' + Drupal.t('Close') + '', classes: 'field-close close gray-button' }
- ]
- }));
- this.show('ops');
- },
-
- /**
- * Adjusts the toolbar to accomodate padding on the PropertyEditor widget.
- *
- * @see PropertyEditorDecorationView._pad().
- */
- _pad: function(editorName) {
- // The whole toolbar must move to the top when the property's DOM element
- // is displayed inline.
- if (this.editor.element.css('display') === 'inline') {
- this.$el.css('top', parseInt(this.$el.css('top'), 10) - 5 + 'px');
- }
-
- // The toolbar must move to the top and the left.
- var $hf = this.$el.find('.edit-toolbar-heightfaker');
- $hf.css({ bottom: '6px', left: '-5px' });
- // When using a WYSIWYG editor, the width of the toolbar must match the
- // width of the editable.
- if (editorName === 'direct-with-wysiwyg') {
- $hf.css({ width: this.editor.element.width() + 10 });
- }
- },
-
- /**
- * Undoes the changes made by _pad().
- *
- * @see PropertyEditorDecorationView._unpad().
- */
- _unpad: function(editorName) {
- // Move the toolbar back to its original position.
- var $hf = this.$el.find('.edit-toolbar-heightfaker');
- $hf.css({ bottom: '1px', left: '' });
- // When using a WYSIWYG editor, restore the width of the toolbar.
- if (editorName === 'direct-with-wysiwyg') {
- $hf.css({ width: '' });
- }
- },
-
- insertWYSIWYGToolGroups: function() {
- this.$el
- .find('.edit-toolbar')
- .append(Drupal.theme('editToolgroup', {
- classes: 'wysiwyg-tabs',
- buttons: []
- }))
- .append(Drupal.theme('editToolgroup', {
- classes: 'wysiwyg',
- buttons: []
- }));
-
- // Animate the toolgroups into visibility.
- var that = this;
- setTimeout(function () {
- that.show('wysiwyg-tabs');
- that.show('wysiwyg');
- }, 0);
- },
-
- /**
- * Renders the Toolbar's markup into the DOM.
- *
- * Note: depending on whether the 'display' property of the $el for which a
- * toolbar is being inserted into the DOM, it will be inserted differently.
- */
- render: function () {
- // Render toolbar.
- this.setElement($(Drupal.theme('editToolbarContainer', {
- id: this.getId()
- })));
-
- // Insert in DOM.
- if (this.$el.css('display') === 'inline') {
- this.$el.prependTo(this.editor.element.offsetParent());
- var pos = this.editor.element.position();
- this.$el.css('left', pos.left).css('top', pos.top);
- }
- else {
- this.$el.insertBefore(this.editor.element);
- }
-
- var that = this;
- // Animate the toolbar into visibility.
- setTimeout(function () {
- that.$el.removeClass('edit-animate-invisible');
- }, 0);
- },
-
- remove: function () {
- if (!this.$el) {
- return;
- }
-
- // Remove after animation.
- var that = this;
- var $el = this.$el;
- this.$el
- .addClass('edit-animate-invisible')
- // Prevent this toolbar from being detected *while* it is being removed.
- .removeAttr('id')
- .find('.edit-toolbar .edit-toolgroup')
- .addClass('edit-animate-invisible')
- .on(Drupal.edit.util.constants.transitionEnd, function (e) {
- $el.remove();
- });
- },
-
- /**
- * Calculates the ID for this toolbar container.
- *
- * Only used to make sane hovering behavior possible.
- *
- * @return string
- * A string that can be used as the ID for this toolbar container.
- */
- getId: function() {
- return this._id;
- },
-
- /**
- * Shows a toolgroup.
- *
- * @param string toolgroup
- * A toolgroup name.
- */
- show: function (toolgroup) {
- this._find(toolgroup).removeClass('edit-animate-invisible');
- },
-
- /**
- * Adds classes to a toolgroup.
- *
- * @param string toolgroup
- * A toolgroup name.
- */
- addClass: function (toolgroup, classes) {
- this._find(toolgroup).addClass(classes);
- },
-
- /**
- * Removes classes from a toolgroup.
- *
- * @param string toolgroup
- * A toolgroup name.
- */
- removeClass: function (toolgroup, classes) {
- this._find(toolgroup).removeClass(classes);
- },
-
- /**
- * Finds a toolgroup.
- *
- * @param string toolgroup
- * A toolgroup name.
- */
- _find: function (toolgroup) {
- return this.$el.find('.edit-toolbar .edit-toolgroup.' + toolgroup);
- }
-});
-
-})(jQuery, _, Backbone, Drupal);
diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
deleted file mode 100644
index 82726c3..0000000
--- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
+++ /dev/null
@@ -1,78 +0,0 @@
-getRequirements());
- }
-
- /**
- * Implements AccessCheckInterface::access().
- */
- public function access(Route $route, Request $request) {
- // @todo Request argument validation and object loading should happen
- // elsewhere in the request processing pipeline:
- // http://drupal.org/node/1798214.
- $this->validateAndUpcastRequestAttributes($request);
-
- return $this->accessEditEntityField($request->attributes->get('entity'), $request->attributes->get('field_name'));
- }
-
- /**
- * Implements EntityFieldAccessCheckInterface::accessEditEntityField().
- */
- public function accessEditEntityField(EntityInterface $entity, $field_name) {
- $entity_type = $entity->entityType();
- // @todo Generalize to all entity types: http://drupal.org/node/1839516.
- return ($entity_type == 'node' && node_access('update', $entity) && field_access('edit', $field_name, $entity_type, $entity));
- }
-
- /**
- * Validates and upcasts request attributes.
- */
- protected function validateAndUpcastRequestAttributes(Request $request) {
- // Load the entity.
- if (!is_object($entity = $request->attributes->get('entity'))) {
- $entity_id = $entity;
- $entity_type = $request->attributes->get('entity_type');
- if (!$entity_type || !entity_get_info($entity_type)) {
- throw new NotFoundHttpException();
- }
- $entity = entity_load($entity_type, $entity_id);
- if (!$entity) {
- throw new NotFoundHttpException();
- }
- $request->attributes->set('entity', $entity);
- }
-
- // Validate the field name and language.
- $field_name = $request->attributes->get('field_name');
- if (!$field_name || !field_info_instance($entity->entityType(), $field_name, $entity->bundle())) {
- throw new NotFoundHttpException();
- }
- $langcode = $request->attributes->get('langcode');
- if (!$langcode || (field_valid_language($langcode) !== $langcode)) {
- throw new NotFoundHttpException();
- }
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheckInterface.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheckInterface.php
deleted file mode 100644
index fe6d918..0000000
--- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheckInterface.php
+++ /dev/null
@@ -1,22 +0,0 @@
-command = $command;
- $this->data = $data;
- }
-
- /**
- * Implements Drupal\Core\Ajax\CommandInterface:render().
- */
- public function render() {
- return array(
- 'command' => $this->command,
- 'data' => $this->data,
- );
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/Ajax/FieldFormCommand.php b/core/modules/edit/lib/Drupal/edit/Ajax/FieldFormCommand.php
deleted file mode 100644
index 76b01c5..0000000
--- a/core/modules/edit/lib/Drupal/edit/Ajax/FieldFormCommand.php
+++ /dev/null
@@ -1,27 +0,0 @@
-register('plugin.manager.edit.processed_text_editor', 'Drupal\edit\Plugin\ProcessedTextEditorManager');
-
- $container->register('access_check.edit.entity_field', 'Drupal\edit\Access\EditEntityFieldAccessCheck')
- ->addTag('access_check');
-
- $container->register('edit.editor.selector', 'Drupal\edit\EditorSelector')
- ->addArgument(new Reference('plugin.manager.edit.processed_text_editor'));
-
- $container->register('edit.metadata.generator', 'Drupal\edit\MetadataGenerator')
- ->addArgument(new Reference('access_check.edit.entity_field'))
- ->addArgument(new Reference('edit.editor.selector'));
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php
deleted file mode 100644
index 5d6f8ed..0000000
--- a/core/modules/edit/lib/Drupal/edit/EditController.php
+++ /dev/null
@@ -1,147 +0,0 @@
-request->get('fields');
- if (!isset($fields)) {
- throw new NotFoundHttpException();
- }
- $metadataGenerator = $this->container->get('edit.metadata.generator');
-
- $metadata = array();
- foreach ($fields as $field) {
- list($entity_type, $entity_id, $field_name, $langcode, $view_mode) = explode(':', $field);
-
- // Load the entity.
- if (!$entity_type || !entity_get_info($entity_type)) {
- throw new NotFoundHttpException();
- }
- $entity = entity_load($entity_type, $entity_id);
- if (!$entity) {
- throw new NotFoundHttpException();
- }
-
- // Validate the field name and language.
- if (!$field_name || !($instance = field_info_instance($entity->entityType(), $field_name, $entity->bundle()))) {
- throw new NotFoundHttpException();
- }
- if (!$langcode || (field_valid_language($langcode) !== $langcode)) {
- throw new NotFoundHttpException();
- }
-
- $metadata[$field] = $metadataGenerator->generate($entity, $instance, $langcode, $view_mode);
- }
-
- return new JsonResponse($metadata);
- }
-
- /**
- * Returns a single field edit form as an Ajax response.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity being edited.
- * @param string $field_name
- * The name of the field that is being edited.
- * @param string $langcode
- * The name of the language for which the field is being edited.
- * @param string $view_mode
- * The view mode the field should be rerendered in.
- * @return \Drupal\Core\Ajax\AjaxResponse
- * The Ajax response.
- */
- public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view_mode) {
- $response = new AjaxResponse();
-
- $form_state = array(
- 'langcode' => $langcode,
- 'no_redirect' => TRUE,
- 'build_info' => array('args' => array($entity, $field_name)),
- );
- $form = drupal_build_form('edit_field_form', $form_state);
-
- if (!empty($form_state['executed'])) {
- // The form submission took care of saving the updated entity. Return the
- // updated view of the field.
- $entity = $form_state['entity'];
- $output = field_view_field($entity->entityType(), $entity, $field_name, $view_mode, $langcode);
-
- $response->addCommand(new FieldFormSavedCommand(drupal_render($output)));
- }
- else {
- $response->addCommand(new FieldFormCommand(drupal_render($form)));
-
- $errors = form_get_errors();
- if (count($errors)) {
- $response->addCommand(new FieldFormValidationErrorsCommand(theme('status_messages')));
- }
- }
-
- // When working with a hidden form, we don't want any CSS or JS to be loaded.
- if (isset($_POST['nocssjs']) && $_POST['nocssjs'] === 'true') {
- drupal_static_reset('drupal_add_css');
- drupal_static_reset('drupal_add_js');
- }
-
- return $response;
- }
-
- /**
- * Returns an Ajax response to render a text field without transformation filters.
- *
- * @param int $entity
- * The entity of which a processed text field is being rerendered.
- * @param string $field_name
- * The name of the (processed text) field that that is being rerendered
- * @param string $langcode
- * The name of the language for which the processed text field is being
- * rererendered.
- * @param string $view_mode
- * The view mode the processed text field should be rerendered in.
- * @return \Drupal\Core\Ajax\AjaxResponse
- * The Ajax response.
- */
- public function getUntransformedText(EntityInterface $entity, $field_name, $langcode, $view_mode) {
- $response = new AjaxResponse();
-
- $output = field_view_field($entity->entityType(), $entity, $field_name, $view_mode, $langcode);
- $langcode = $output['#language'];
- // Direct text editing is only supported for single-valued fields.
- $editable_text = check_markup($output['#items'][0]['value'], $output['#items'][0]['format'], $langcode, FALSE, array(FILTER_TYPE_TRANSFORM_REVERSIBLE, FILTER_TYPE_TRANSFORM_IRREVERSIBLE));
- $response->addCommand(new FieldRenderedWithoutTransformationFiltersCommand($editable_text));
-
- return $response;
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/EditorSelector.php b/core/modules/edit/lib/Drupal/edit/EditorSelector.php
deleted file mode 100644
index 5c44954..0000000
--- a/core/modules/edit/lib/Drupal/edit/EditorSelector.php
+++ /dev/null
@@ -1,167 +0,0 @@
-processedTextEditorManager = $processed_text_editor_manager;
- }
-
- /**
- * Implements \Drupal\edit\EditorSelectorInterface::getEditor().
- */
- public function getEditor($formatter_type, FieldInstance $instance, array $items) {
- // Check if the formatter defines an appropriate in-place editor. For
- // example, text formatters displaying untrimmed text can choose to use the
- // 'direct' editor. If the formatter doesn't specify, fall back to the
- // 'form' editor, since that can work for any field. Formatter definitions
- // can use 'disabled' to explicitly opt out of in-place editing.
- $formatter_info = field_info_formatter_types($formatter_type);
- $editor = isset($formatter_info['edit']['editor']) ? $formatter_info['edit']['editor'] : 'form';
- if ($editor == 'disabled') {
- return;
- }
-
- // The same text formatters can be used for single-valued and multivalued
- // fields and for processed and unprocessed text, so we can't rely on the
- // formatter definition for the final determination, because:
- // - The direct editor does not work for multivalued fields.
- // - Processed text can benefit from a WYSIWYG editor.
- // - Empty processed text without an already selected format requires a form
- // to select one.
- // @todo The processed text logic is too coupled to text fields. Figure out
- // how to generalize to other textual field types.
- // @todo All of this might hint at formatter *definitions* not being the
- // ideal place for editor specification. Moving the determination to
- // something that works with instantiated formatters, not just their
- // definitions, could alleviate that, but might come with its own
- // challenges.
- if ($editor == 'direct') {
- $field = field_info_field($instance['field_name']);
- if ($field['cardinality'] != 1) {
- // The direct editor does not work for multivalued fields.
- $editor = 'form';
- }
- elseif (!empty($instance['settings']['text_processing'])) {
- $format_id = $items[0]['format'];
- if (isset($format_id)) {
- $wysiwyg_plugin = $this->getProcessedTextEditorPlugin();
- if (isset($wysiwyg_plugin) && $wysiwyg_plugin->checkFormatCompatibility($format_id)) {
- // Yay! Even though the text is processed, there's a WYSIWYG editor
- // that can work with it.
- $editor = 'direct-with-wysiwyg';
- }
- else {
- // @todo We might not have to downgrade all the way to 'form'. The
- // 'direct' editor might be appropriate for some kinds of
- // processed text.
- $editor = 'form';
- }
- }
- else {
- // If a format is not yet selected, a form is needed to select one.
- $editor = 'form';
- }
- }
- }
-
- return $editor;
- }
-
- /**
- * Implements \Drupal\edit\EditorSelectorInterface::getAllEditorAttachments().
- */
- public function getAllEditorAttachments() {
- $this->getProcessedTextEditorPlugin();
- if (!isset($this->processedTextEditorPlugin)) {
- return array();
- }
-
- $js = array();
-
- // Add library and settings for the selected processed text editor plugin.
- $definition = $this->processedTextEditorPlugin->getDefinition();
- if (!empty($definition['library'])) {
- $js['library'][] = array($definition['library']['module'], $definition['library']['name']);
- }
- $this->processedTextEditorPlugin->addJsSettings();
-
- // Also add the setting to register it with Create.js
- if (!empty($definition['propertyEditorName'])) {
- $js['js'][] = array(
- 'data' => array(
- 'edit' => array(
- 'wysiwygEditorWidgetName' => $definition['propertyEditorName'],
- ),
- ),
- 'type' => 'setting'
- );
- }
-
- return $js;
- }
-
- /**
- * Returns the plugin to use for the 'direct-with-wysiwyg' editor.
- *
- * @return \Drupal\edit\Plugin\ProcessedTextEditorInterface
- * The editor plugin.
- *
- * @todo We currently only support one plugin (the first one returned by the
- * manager) for the 'direct-with-wysiwyg' editor on any given page. Enhance
- * this to allow different ones per element (e.g., Aloha for one text field
- * and CKEditor for another one).
- *
- * @todo The terminology here is confusing. 'direct-with-wysiwyg' is one of
- * several possible "editor"s for processed text. When using it, we need to
- * integrate a particular WYSIWYG editor, which in Create.js is called a
- * "PropertyEditor widget", but we're not yet including "widget" in the name
- * of ProcessedTextEditorInterface to minimize confusion with Field API
- * widgets. So, we're currently refering to these as "plugins", which is
- * correct in that it's using Drupal's Plugin API, but less informative than
- * naming it "widget" or similar.
- */
- protected function getProcessedTextEditorPlugin() {
- if (!isset($this->processedTextEditorPlugin)) {
- $definitions = $this->processedTextEditorManager->getDefinitions();
- if (count($definitions)) {
- $plugin_ids = array_keys($definitions);
- $plugin_id = $plugin_ids[0];
- $this->processedTextEditorPlugin = $this->processedTextEditorManager->createInstance($plugin_id);
- }
- }
- return $this->processedTextEditorPlugin;
- }
-}
diff --git a/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php b/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php
deleted file mode 100644
index ed7e2c8..0000000
--- a/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php
+++ /dev/null
@@ -1,55 +0,0 @@
-init($form_state, $entity, $field_name);
- }
-
- // Add the field form.
- field_attach_form($form_state['entity']->entityType(), $form_state['entity'], $form, $form_state, $form_state['langcode'], array('field_name' => $form_state['field_name']));
-
- // Add a submit button. Give it a class for easy JavaScript targeting.
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save'),
- '#attributes' => array('class' => array('edit-form-submit')),
- );
-
- // Add validation and submission handlers.
- $form['#validate'][] = array($this, 'validate');
- $form['#submit'][] = array($this, 'submit');
-
- // Simplify it for optimal in-place use.
- $this->simplify($form, $form_state);
-
- return $form;
- }
-
- /**
- * Initialize the form state and the entity before the first form build.
- */
- protected function init(array &$form_state, EntityInterface $entity, $field_name) {
- // @todo Rather than special-casing $node->revision, invoke prepareEdit()
- // once http://drupal.org/node/1863258 lands.
- if ($entity->entityType() == 'node') {
- $entity->setNewRevision(in_array('revision', variable_get('node_options_' . $entity->bundle(), array())));
- $entity->log = NULL;
- }
-
- $form_state['entity'] = $entity;
- $form_state['field_name'] = $field_name;
- }
-
- /**
- * Validates the form.
- */
- public function validate(array $form, array &$form_state) {
- $entity = $this->buildEntity($form, $form_state);
- field_attach_form_validate($entity->entityType(), $entity, $form, $form_state, array('field_name' => $form_state['field_name']));
- }
-
- /**
- * Saves the entity with updated values for the edited field.
- */
- public function submit(array $form, array &$form_state) {
- $form_state['entity'] = $this->buildEntity($form, $form_state);
- $form_state['entity']->save();
- }
-
- /**
- * Returns a cloned entity containing updated field values.
- *
- * Calling code may then validate the returned entity, and if valid, transfer
- * it back to the form state and save it.
- */
- protected function buildEntity(array $form, array &$form_state) {
- $entity = clone $form_state['entity'];
-
- // @todo field_attach_submit() only "submits" to the in-memory $entity
- // object, not to anywhere persistent. Consider renaming it to minimize
- // confusion: http://drupal.org/node/1846648.
- field_attach_submit($entity->entityType(), $entity, $form, $form_state, array('field_name' => $form_state['field_name']));
-
- // @todo Refine automated log messages and abstract them to all entity
- // types: http://drupal.org/node/1678002.
- if ($entity->entityType() == 'node' && $entity->isNewRevision() && !isset($entity->log)) {
- $instance = field_info_instance($entity->entityType(), $form_state['field_name'], $entity->bundle());
- $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $instance['label']));
- }
-
- return $entity;
- }
-
- /**
- * Simplifies the field edit form for in-place editing.
- *
- * This function:
- * - Hides the field label inside the form, because JavaScript displays it
- * outside the form.
- * - Adjusts textarea elements to fit their content.
- *
- * @param array $form
- * An associative array containing the structure of the form.
- */
- protected function simplify(array &$form, array &$form_state) {
- $field_name = $form_state['field_name'];
- $langcode = $form_state['langcode'];
-
- $widget_element =& $form[$field_name][$langcode];
-
- // Hide the field label from displaying within the form, because JavaScript
- // displays the equivalent label that was provided within an HTML data
- // attribute of the field's display element outside of the form. Do this for
- // widgets without child elements (like Option widgets) as well as for ones
- // with per-delta elements. Skip single checkboxes, because their title is
- // key to their UI. Also skip widgets with multiple subelements, because in
- // that case, per-element labeling is informative.
- $num_children = count(element_children($widget_element));
- if ($num_children == 0 && $widget_element['#type'] != 'checkbox') {
- $widget_element['#title_display'] = 'invisible';
- }
- if ($num_children == 1 && isset($widget_element[0]['value'])) {
- // @todo While most widgets name their primary element 'value', not all
- // do, so generalize this.
- $widget_element[0]['value']['#title_display'] = 'invisible';
- }
-
- // Adjust textarea elements to fit their content.
- if (isset($widget_element[0]['value']['#type']) && $widget_element[0]['value']['#type'] == 'textarea') {
- $lines = count(explode("\n", $widget_element[0]['value']['#default_value']));
- $widget_element[0]['value']['#rows'] = $lines + 1;
- }
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
deleted file mode 100644
index bdbdf10..0000000
--- a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php
+++ /dev/null
@@ -1,87 +0,0 @@
-accessChecker = $access_checker;
- $this->editorSelector = $editor_selector;
- }
-
- /**
- * Implements \Drupal\edit\MetadataGeneratorInterface::generate().
- */
- public function generate(EntityInterface $entity, FieldInstance $instance, $langcode, $view_mode) {
- $field_name = $instance['field_name'];
-
- // Early-return if user does not have access.
- $access = $this->accessChecker->accessEditEntityField($entity, $field_name);
- if (!$access) {
- return array('access' => FALSE);
- }
-
- $label = $instance['label'];
- $formatter_id = $instance->getFormatter($view_mode)->getPluginId();
- $items = $entity->get($field_name);
- $items = $items[$langcode];
- $editor = $this->editorSelector->getEditor($formatter_id, $instance, $items);
- $metadata = array(
- 'label' => $label,
- 'access' => TRUE,
- 'editor' => $editor,
- 'aria' => t('Entity @type @id, field @field', array('@type' => $entity->entityType(), '@id' => $entity->id(), '@field' => $label)),
- );
- // Additional metadata for WYSIWYG editor integration.
- if ($editor === 'direct-with-wysiwyg') {
- $format_id = $items[0]['format'];
- $metadata['format'] = $format_id;
- $metadata['formatHasTransformations'] = $this->textFormatHasTransformationFilters($format_id);
- }
- return $metadata;
- }
-
- /**
- * Returns whether the text format has transformation filters.
- */
- protected function textFormatHasTransformationFilters($format_id) {
- return (bool) count(array_intersect(array(FILTER_TYPE_TRANSFORM_REVERSIBLE, FILTER_TYPE_TRANSFORM_IRREVERSIBLE), filter_get_filter_types_by_format($format_id)));
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php b/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php
deleted file mode 100644
index 9e4fb5d..0000000
--- a/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php
+++ /dev/null
@@ -1,41 +0,0 @@
-discovery = new AnnotatedClassDiscovery('edit', 'processed_text_editor');
- $this->discovery = new AlterDecorator($this->discovery, 'edit_wysiwyg');
- $this->discovery = new CacheDecorator($this->discovery, 'edit:wysiwyg');
- $this->factory = new DefaultFactory($this->discovery);
- }
-
-}
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php b/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
deleted file mode 100644
index 1aca55d..0000000
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditorSelectionTest.php
+++ /dev/null
@@ -1,240 +0,0 @@
- 'In-place field editor selection',
- 'description' => 'Tests in-place field editor selection.',
- 'group' => 'Edit',
- );
- }
-
- /**
- * Sets the default field storage backend for fields created during tests.
- */
- function setUp() {
- parent::setUp();
-
- $this->installSchema('system', 'variable');
- $this->enableModules(array('field', 'field_sql_storage', 'field_test'));
-
- // Set default storage backend.
- variable_set('field_storage_default', $this->default_storage);
-
- // @todo Rather than using the real ProcessedTextEditorManager, which can
- // find all text editor plugins in the codebase, create a mock one for
- // testing that is populated with only the ones we want to test.
- $text_editor_manager = new ProcessedTextEditorManager();
-
- $this->editorSelector = new EditorSelector($text_editor_manager);
- }
-
- /**
- * Creates a field and an instance of it.
- *
- * @param string $field_name
- * The field name.
- * @param string $type
- * The field type.
- * @param int $cardinality
- * The field's cardinality.
- * @param string $label
- * The field's label (used everywhere: widget label, formatter label).
- * @param array $instance_settings
- * @param string $widget_type
- * The widget type.
- * @param array $widget_settings
- * The widget settings.
- * @param string $formatter_type
- * The formatter type.
- * @param array $formatter_settings
- * The formatter settings.
- */
- function createFieldWithInstance($field_name, $type, $cardinality, $label, $instance_settings, $widget_type, $widget_settings, $formatter_type, $formatter_settings) {
- $field = $field_name . '_field';
- $this->$field = array(
- 'field_name' => $field_name,
- 'type' => $type,
- 'cardinality' => $cardinality,
- );
- $this->$field_name = field_create_field($this->$field);
-
- $instance = $field_name . '_instance';
- $this->$instance = array(
- 'field_name' => $field_name,
- 'entity_type' => 'test_entity',
- 'bundle' => 'test_bundle',
- 'label' => $label,
- 'description' => $label,
- 'weight' => mt_rand(0, 127),
- 'settings' => $instance_settings,
- 'widget' => array(
- 'type' => $widget_type,
- 'label' => $label,
- 'settings' => $widget_settings,
- ),
- 'display' => array(
- 'default' => array(
- 'label' => 'above',
- 'type' => $formatter_type,
- 'settings' => $formatter_settings
- ),
- ),
- );
- field_create_instance($this->$instance);
- }
-
- /**
- * Retrieves the FieldInstance object for the given field and returns the
- * editor that Edit selects.
- */
- function getSelectedEditor($items, $field_name, $display = 'default') {
- $field_instance = field_info_instance('test_entity', $field_name, 'test_bundle');
- return $this->editorSelector->getEditor($field_instance['display'][$display]['type'], $field_instance, $items);
- }
-
- /**
- * Tests a textual field, without/with text processing, with cardinality 1 and
- * >1, always without a WYSIWYG editor present.
- */
- function testText() {
- $field_name = 'field_text';
- $this->createFieldWithInstance(
- $field_name, 'text', 1, 'Simple text field',
- // Instance settings.
- array('text_processing' => 0),
- // Widget type & settings.
- 'text_textfield',
- array('size' => 42),
- // 'default' formatter type & settings.
- 'text_default',
- array()
- );
-
- // Pretend there is an entity with these items for the field.
- $items = array(array('value' => 'Hello, world!', 'format' => 'full_html'));
-
- // Editor selection without text processing, with cardinality 1.
- $this->assertEqual('direct', $this->getSelectedEditor($items, $field_name), "Without text processing, cardinality 1, the 'direct' editor is selected.");
-
- // Editor selection with text processing, cardinality 1.
- $this->field_text_instance['settings']['text_processing'] = 1;
- field_update_instance($this->field_text_instance);
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With text processing, cardinality 1, the 'form' editor is selected.");
-
- // Editor selection without text processing, cardinality 1 (again).
- $this->field_text_instance['settings']['text_processing'] = 0;
- field_update_instance($this->field_text_instance);
- $this->assertEqual('direct', $this->getSelectedEditor($items, $field_name), "Without text processing again, cardinality 1, the 'direct' editor is selected.");
-
- // Editor selection without text processing, cardinality >1
- $this->field_text_field['cardinality'] = 2;
- field_update_field($this->field_text_field);
- $items[] = array('value' => 'Hallo, wereld!', 'format' => 'full_html');
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "Without text processing, cardinality >1, the 'form' editor is selected.");
-
- // Editor selection with text processing, cardinality >1
- $this->field_text_instance['settings']['text_processing'] = 1;
- field_update_instance($this->field_text_instance);
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With text processing, cardinality >1, the 'form' editor is selected.");
- }
-
- /**
- * Tests a textual field, with text processing, with cardinality 1 and >1,
- * always with a ProcessedTextEditor plug-in present, but with varying text
- * format compatibility.
- */
- function testTextWysiwyg() {
- $field_name = 'field_textarea';
- $this->createFieldWithInstance(
- $field_name, 'text', 1, 'Long text field',
- // Instance settings.
- array('text_processing' => 1),
- // Widget type & settings.
- 'text_textarea',
- array('size' => 42),
- // 'default' formatter type & settings.
- 'text_default',
- array()
- );
-
- // ProcessedTextEditor plug-in compatible with the full_html text format.
- state()->set('edit_test.compatible_format', 'full_html');
-
- // Pretend there is an entity with these items for the field.
- $items = array(array('value' => 'Hello, world!', 'format' => 'filtered_html'));
-
- // Editor selection with cardinality 1, without compatible text format.
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "Without cardinality 1, and the filtered_html text format, the 'form' editor is selected.");
-
- // Editor selection with cardinality 1, with compatible text format.
- $items[0]['format'] = 'full_html';
- $this->assertEqual('direct-with-wysiwyg', $this->getSelectedEditor($items, $field_name), "With cardinality 1, and the full_html text format, the 'direct-with-wysiwyg' editor is selected.");
-
- // Editor selection with text processing, cardinality >1
- $this->field_textarea_field['cardinality'] = 2;
- field_update_field($this->field_textarea_field);
- $items[] = array('value' => 'Hallo, wereld!', 'format' => 'full_html');
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality >1, and both items using the full_html text format, the 'form' editor is selected.");
- }
-
- /**
- * Tests a number field, with cardinality 1 and >1.
- */
- function testNumber() {
- $field_name = 'field_nr';
- $this->createFieldWithInstance(
- $field_name, 'number_integer', 1, 'Simple number field',
- // Instance settings.
- array(),
- // Widget type & settings.
- 'number',
- array(),
- // 'default' formatter type & settings.
- 'number_integer',
- array()
- );
-
- // Pretend there is an entity with these items for the field.
- $items = array(42, 43);
-
- // Editor selection with cardinality 1.
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality 1, the 'form' editor is selected.");
-
- // Editor selection with cardinality >1.
- $this->field_nr_field['cardinality'] = 2;
- field_update_field($this->field_nr_field);
- $this->assertEqual('form', $this->getSelectedEditor($items, $field_name), "With cardinality >1, the 'form' editor is selected.");
- }
-
-}
diff --git a/core/modules/edit/tests/modules/edit_test.info b/core/modules/edit/tests/modules/edit_test.info
deleted file mode 100644
index 4df4a3f..0000000
--- a/core/modules/edit/tests/modules/edit_test.info
+++ /dev/null
@@ -1,6 +0,0 @@
-name = Edit test
-description = Support module for the Edit module tests.
-core = 8.x
-package = Testing
-version = VERSION
-hidden = TRUE
diff --git a/core/modules/edit/tests/modules/edit_test.module b/core/modules/edit/tests/modules/edit_test.module
deleted file mode 100644
index d74528d..0000000
--- a/core/modules/edit/tests/modules/edit_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-get('edit_test.compatible_format') == $format_id;
- }
-
-}
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php
index a2e49e3..957bd4a 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php
@@ -85,7 +85,7 @@ public function getId() {
/**
* Get the type URI.
*
- * @todo Once RdfMappingManager has a mapOutputTypes event, use that instead
+ * @todo Once RdfMappingManager has a mapBundleForOutput event, use that instead
* of simply returning the site schema URI.
*/
public function getTypeUri() {
@@ -93,12 +93,12 @@ public function getTypeUri() {
$bundle = $this->entity->bundle();
switch ($this->format) {
case 'drupal_jsonld':
- $schema_path = SiteSchema::CONTENT_DEPLOYMENT;
+ $schema_id = SiteSchema::CONTENT_DEPLOYMENT;
break;
case 'jsonld':
- $schema_path = SiteSchema::SYNDICATION;
+ $schema_id = SiteSchema::SYNDICATION;
}
- $schema = $this->siteSchemaManager->getSchema($schema_path);
+ $schema = $this->siteSchemaManager->getSchema($schema_id);
return $schema->bundle($entity_type, $bundle)->getUri();
}
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php b/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php
index c4422aa..3cbfae4 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php
@@ -46,7 +46,7 @@ function testSchemaSerialization() {
$parsed_term = $decoded[0];
$this->assertEqual($parsed_term->{'@id'}, $bundle_schema->getUri(), 'JSON-LD for schema term uses correct @id.');
- $this->assertEqual($parsed_term->{'@type'}, 'http://www.w3.org/2000/01/rdf-schema#class', 'JSON-LD for schema term uses correct @type.');
+ $this->assertEqual($parsed_term->{'@type'}, 'http://www.w3.org/2000/01/rdf-schema#Class', 'JSON-LD for schema term uses correct @type.');
// The @id and @type should be placed in the beginning of the array.
$array_keys = array_keys((array) $parsed_term);
$this->assertEqual(array('@id', '@type'), array_slice($array_keys, 0, 2), 'JSON-LD keywords are placed before other properties.');
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index a37679c..d53f10e 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -811,53 +811,6 @@ function node_type_set_defaults($info = array()) {
}
/**
- * Implements hook_rdf_mapping().
- */
-function node_rdf_mapping() {
- return array(
- array(
- 'type' => 'node',
- 'bundle' => RDF_DEFAULT_BUNDLE,
- 'mapping' => array(
- 'rdftype' => array('sioc:Item', 'foaf:Document'),
- 'title' => array(
- 'predicates' => array('dc:title'),
- ),
- 'created' => array(
- 'predicates' => array('dc:date', 'dc:created'),
- 'datatype' => 'xsd:dateTime',
- 'callback' => 'date_iso8601',
- ),
- 'changed' => array(
- 'predicates' => array('dc:modified'),
- 'datatype' => 'xsd:dateTime',
- 'callback' => 'date_iso8601',
- ),
- 'body' => array(
- 'predicates' => array('content:encoded'),
- ),
- 'uid' => array(
- 'predicates' => array('sioc:has_creator'),
- 'type' => 'rel',
- ),
- 'name' => array(
- 'predicates' => array('foaf:name'),
- ),
- 'comment_count' => array(
- 'predicates' => array('sioc:num_replies'),
- 'datatype' => 'xsd:integer',
- ),
- 'last_activity' => array(
- 'predicates' => array('sioc:last_activity_date'),
- 'datatype' => 'xsd:dateTime',
- 'callback' => 'date_iso8601',
- ),
- ),
- ),
- );
-}
-
-/**
* Determines whether a node hook exists.
*
* @param string $type
diff --git a/core/modules/rdf/lib/Drupal/rdf/BundleRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/BundleRdfMappingStorageController.php
new file mode 100644
index 0000000..051623a
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/BundleRdfMappingStorageController.php
@@ -0,0 +1,19 @@
+siteSchema->bundle($entity->entity_type, $entity->bundle);
+ }
+
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php
index 764c2f9..f58658d 100644
--- a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php
+++ b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php
@@ -35,11 +35,41 @@ public function mapTypesFromInput(\Drupal\rdf\MapTypesFromInputEvent $event) {
}
}
+ public function mapBundleForOutput(\Drupal\rdf\MapBundleForOutputEvent $event) {
+ $term_schema = $event->getTermSchema();
+ // @todo When the $schema is SYNDICATION, allow sites to exclude the site
+ // schema URI from the mapping.
+ $site_schema_curie = $term_schema->getCurie();
+ $event->addTypes(array($site_schema_curie));
+
+ $config = config($term_schema->getMappingConfigName());
+ $types = $config->get('types');
+ if (!empty($types)) {
+ $event->addTypes($types);
+ }
+ }
+
+ public function mapFieldForOutput(\Drupal\rdf\MapFieldForOutputEvent $event) {
+ $term_schema = $event->getTermSchema();
+ // @todo When the $schema is SYNDICATION, allow sites to exclude the site
+ // schema URI from the mapping.
+ $site_schema_curie = $term_schema->getCurie();
+ $event->addPredicates(array($site_schema_curie));
+
+ $config = config($term_schema->getMappingConfigName());
+ $curies = $config->get('properties');
+ if (!empty($curies)) {
+ $event->addPredicates($curies);
+ }
+ }
+
/**
* Implements EventSubscriberInterface::getSubscribedEvents().
*/
static function getSubscribedEvents() {
$events[RdfMappingEvents::MAP_TYPES_FROM_INPUT] = 'mapTypesFromInput';
+ $events[RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT] = 'mapBundleForOutput';
+ $events[RdfMappingEvents::MAP_FIELD_FOR_OUTPUT] = 'mapFieldForOutput';
return $events;
}
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php
index 123493b..cf04c94 100644
--- a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php
+++ b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php
@@ -50,10 +50,10 @@ public function routes(RouteBuildEvent $event) {
foreach ($this->siteSchemaManager->getSchemas() as $schema) {
$routes = $schema->getRoutes();
foreach ($routes as $controller => $pattern) {
- $schema_path = $schema->getPath();
+ $schema_id = $schema->getId();
$route = new Route($pattern, array(
'_controller' => 'Drupal\rdf\SiteSchema\SchemaController::' . $controller,
- 'schema_path' => $schema_path,
+ 'schema_id' => $schema_id,
), array(
'_method' => 'GET',
'_access' => 'TRUE',
@@ -61,7 +61,7 @@ public function routes(RouteBuildEvent $event) {
// Create the route name to use in the RouteCollection. Remove the
// trailing slash and replace characters, so that a path such as
// site-schema/syndication/ becomes rdf.site_schema.syndication.
- $route_name = 'rdf.' . str_replace(array('-','/'), array('_', '.'), substr_replace($schema_path ,"",-1));
+ $route_name = 'rdf.' . str_replace(array('-','/'), array('_', '.'), substr_replace($schema_id ,"",-1));
$collection->add($route_name, $route);
}
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/FieldRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/FieldRdfMappingStorageController.php
new file mode 100644
index 0000000..04b5b7f
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/FieldRdfMappingStorageController.php
@@ -0,0 +1,20 @@
+siteSchema->field($entity->entity_type, $entity->bundle, $entity->field_name);
+ }
+
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php
new file mode 100644
index 0000000..59bfce0
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php
@@ -0,0 +1,59 @@
+termSchema = $term_schema;
+ $this->curies = array();
+ }
+
+ public function getTermSchema() {
+ return $this->termSchema;
+ }
+
+ /**
+ * Add RDF types to the CURIEs array.
+ *
+ * @param array $curies
+ *
+ * @todo Add namespace IDs.
+ */
+ public function addTypes($curies) {
+ if (!is_array($curies)) {
+ $curies = array($curies);
+ }
+ $this->curies = array_merge($this->curies, $curies);
+ }
+
+ public function getCuries() {
+ return $this->curies;
+ }
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/MapFieldForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/MapFieldForOutputEvent.php
new file mode 100644
index 0000000..2294c3a
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/MapFieldForOutputEvent.php
@@ -0,0 +1,71 @@
+termSchema = $term_schema;
+ $this->predicates = array();
+ }
+
+ public function getTermSchema() {
+ return $this->termSchema;
+ }
+
+ /**
+ * Add CURIEs to the predicates array.
+ *
+ * @param array $curies
+ *
+ * @todo Add namespace IDs.
+ */
+ public function addPredicates($curies) {
+ if (!is_array($curies)) {
+ $curies = array($curies);
+ }
+ $this->predicates = array_merge($this->predicates, $curies);
+ }
+
+ public function getPredicates() {
+ return $this->predicates;
+ }
+
+ public function getDatatype() {
+ return $this->datatype;
+ }
+
+ public function getDatatypeCallback() {
+ return $this->datatype_callback;
+ }
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php
new file mode 100644
index 0000000..ec30afd
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php
@@ -0,0 +1,74 @@
+mid;
+ }
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php
new file mode 100644
index 0000000..7c1dc1c
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php
@@ -0,0 +1,95 @@
+mid;
+ }
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php b/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php
index b64ae91..4ac035f 100644
--- a/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php
+++ b/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php
@@ -12,8 +12,9 @@
*/
abstract class RdfConstants {
const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
+ const RDF_PROPERTY = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property';
// RDF Schema terms.
- const RDFS_CLASS = 'http://www.w3.org/2000/01/rdf-schema#class';
+ const RDFS_CLASS = 'http://www.w3.org/2000/01/rdf-schema#Class';
const RDFS_DOMAIN = 'http://www.w3.org/2000/01/rdf-schema#domain';
const RDFS_IS_DEFINED_BY = 'http://www.w3.org/2000/01/rdf-schema#isDefinedBy';
const RDFS_RANGE = 'http://www.w3.org/2000/01/rdf-schema#range';
diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php
index 0e3fdae..f74c791 100644
--- a/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php
+++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php
@@ -26,4 +26,24 @@
*/
const MAP_TYPES_FROM_INPUT = 'rdf.map_types_from_input';
+ /**
+ * Maps a bundle to corresponding RDF URIs.
+ *
+ * In contrast to MAP_INPUT_TYPES, this event is triggered when RDF is being
+ * published. Modules can use this event to add RDF types to a mapping, which
+ * will then be published in the site's RDFa, JSON-LD, etc. However, a module
+ * does not have to use this event to add RDF types. RDF module manages an
+ * RDF mapping configuration file for each bundle which modules can also use
+ * to register mappings.
+ *
+ * @todo Add a note about this being cached once it is.
+ *
+ * @see \Drupal\rdf\RdfMappingManager
+ *
+ * @var string
+ */
+ const MAP_BUNDLE_FOR_OUTPUT = 'rdf.map_bundle_for_output';
+
+ const MAP_FIELD_FOR_OUTPUT = 'rdf.map_field_for_output';
+
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php
index 90588e9..6ab6341 100644
--- a/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php
+++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php
@@ -10,6 +10,8 @@
use ReflectionClass;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\rdf\MapTypesFromInputEvent;
+use Drupal\rdf\MapBundleForOutputEvent;
+use Drupal\rdf\MapFieldForOutputEvent;
use Drupal\rdf\RdfMappingEvents;
use Drupal\rdf\SiteSchema\BundleSchema;
use Drupal\rdf\SiteSchema\SiteSchema;
@@ -76,6 +78,40 @@ public function getTypedDataIdsFromTypeUris($input_rdf_types) {
}
/**
+ * Convert Typed Data IDs to an array of RDF types.
+ *
+ * @param string $entity_type
+ * The entity type of the bundle which the types correspond to.
+ * @param string $bundle
+ * The name of the bundle which the types correspond to.
+ * @param string $schema_id
+ * The site schema which is being mapped to.
+ */
+ public function getBundleMapping($entity_type, $bundle, $schema_id = SiteSchema::SYNDICATION) {
+ $site_schema = $this->siteSchemaManager->getSchema($schema_id);
+ $term_schema = $site_schema->bundle($entity_type, $bundle);
+ // Get the site schema URI which corresponds to the bundle.
+ $curies = $this->mapBundleForOutput($term_schema);
+ return $curies;
+ }
+
+ public function getFieldMapping($entity_type, $bundle, $field_name, $schema_id = SiteSchema::SYNDICATION) {
+ $site_schema = $this->siteSchemaManager->getSchema($schema_id);
+ $term_schema = $site_schema->field($entity_type, $bundle, $field_name);
+ return $this->mapFieldForOutput($term_schema);
+ }
+
+ public function getBundleMappingConfig($entity_type, $bundle, $schema_id = SiteSchema::SYNDICATION) {
+ $bundle_schema = $this->siteSchemaManager->getSchema($schema_id)->bundle($entity_type, $bundle);
+ return $bundle_schema->getMappingConfig();
+ }
+
+ public function getFieldMappingConfig($entity_type, $bundle, $field_name, $schema_id = SiteSchema::SYNDICATION) {
+ $field_schema = $this->siteSchemaManager->getSchema($schema_id)->field($entity_type, $bundle, $field_name);
+ return $field_schema->getMappingConfig();
+ }
+
+ /**
* Map an array of incoming URIs to an internal site schema URI.
*
* @param array $input_rdf_types
@@ -98,4 +134,30 @@ protected function mapTypesFromInput($input_rdf_types) {
return $mapping_event->getSiteSchemaUri();
}
+
+ protected function mapBundleForOutput($term_schema) {
+ $mapping = array();
+ $typeMap = new MapBundleForOutputEvent($term_schema);
+ $this->dispatcher->dispatch(RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT, $typeMap);
+ $types = $typeMap->getCuries();
+ if (!empty($types)) {
+ $mapping['types'] = $types;
+ }
+ return $mapping;
+ }
+
+ protected function mapFieldForOutput($term_schema) {
+ $mapping = array();
+ $map_event = new MapFieldForOutputEvent($term_schema);
+ $this->dispatcher->dispatch(RdfMappingEvents::MAP_FIELD_FOR_OUTPUT, $map_event);
+
+ $predicates = $map_event->getPredicates();
+ if (!empty($predicates)) {
+ $mapping['properties'] = $predicates;
+ $mapping['datatype'] = $map_event->getDatatype();
+ $mapping['datatype_callback'] = $map_event->getDatatypeCallback();
+ }
+ return array_filter($mapping);
+ }
+
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfMappingStorageControllerBase.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingStorageControllerBase.php
new file mode 100644
index 0000000..afbe5d7
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingStorageControllerBase.php
@@ -0,0 +1,40 @@
+siteSchema = drupal_container()->get('rdf.site_schema_manager')->getSchema(SiteSchema::SYNDICATION);
+ }
+
+ /**
+ * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::save().
+ */
+ public function save(EntityInterface $entity) {
+ if (!isset($entity->mid)) {
+ $entity->mid = $this->getTermSchema($entity)->getMappingConfigId();
+ }
+ parent::save($entity);
+ }
+
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php
index 2c92696..e82b9ed 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php
@@ -22,6 +22,8 @@ class BundleSchema extends EntitySchema {
*/
public static $uriPattern = '{entity_type}/{bundle}';
+ protected $configPrefix = 'rdf.mapping.bundle';
+
/**
* The bundle that this term identifies.
*
@@ -45,11 +47,14 @@ public function __construct($site_schema, $entity_type, $bundle) {
}
/**
- * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri().
+ * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath().
*/
- public function getUri() {
- $path = str_replace(array('{entity_type}', '{bundle}'), array($this->entityType, $this->bundle), static::$uriPattern);
- return $this->siteSchema->getUri() . $path;
+ public function getPath() {
+ return $this->siteSchema->getPath() . $this->prepareUriPattern();
+ }
+
+ protected function prepareUriPattern() {
+ return str_replace(array('{entity_type}', '{bundle}'), array($this->entityType, $this->bundle), static::$uriPattern);
}
/**
@@ -61,4 +66,10 @@ public function getProperties() {
return $properties;
}
+ protected function getMappingConfigKeys() {
+ $keys = parent::getMappingConfigKeys();
+ $keys['bundle'] = $this->bundle;
+ return $keys;
+ }
+
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php
index 48a69fc..a1665e8 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php
@@ -54,11 +54,11 @@ public function getGraph() {
}
/**
- * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri().
+ * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath().
*/
- public function getUri() {
+ public function getPath() {
$path = str_replace('{entity_type}', $this->entityType , static::$uriPattern);
- return $this->siteSchema->getUri() . $path;
+ return $this->siteSchema->getPath() . $path;
}
/**
@@ -70,4 +70,11 @@ public function getProperties() {
return $properties;
}
+ protected function getMappingConfigKeys() {
+ return array(
+ 'schema_id' => $this->siteSchema->getId(),
+ 'entity_type' => $this->entityType,
+ );
+ }
+
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php
new file mode 100644
index 0000000..0d56ca5
--- /dev/null
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php
@@ -0,0 +1,105 @@
+entityType = $entity_type;
+ $this->bundle = $bundle;
+ $this->fieldName = $field_name;
+ }
+
+ /**
+ * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getGraph().
+ *
+ * @todo Loop through all fields and add their RDF descriptions.
+ */
+ public function getGraph() {
+ // @todo Implement this.
+ }
+
+ /**
+ * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath().
+ */
+ public function getPath() {
+ return $this->siteSchema->getPath() . $this->prepareUriPattern();
+ }
+
+ protected function prepareUriPattern() {
+ return str_replace(array('{entity_type}', '{bundle}', '{field_name}'), array($this->entityType, $this->bundle, $this->fieldName), static::$uriPattern);
+ }
+
+ /**
+ * Overrides \Drupal\rdf\SiteSchema\SchemaTermBase::getProperties().
+ */
+ public function getProperties() {
+ $properties = parent::getProperties();
+ $properties[RdfConstants::RDF_TYPE] = RdfConstants::RDF_PROPERTY;
+ return $properties;
+ }
+
+ protected function getMappingConfigKeys() {
+ return array(
+ 'schema_id' => $this->siteSchema->getId(),
+ 'entity_type' => $this->entityType,
+ 'bundle' => $this->bundle,
+ 'field_name' => $this->fieldName,
+ );
+ }
+
+}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php
index b60eb84..9617401 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php
@@ -42,7 +42,7 @@ public function setContainer(ContainerInterface $container = NULL) {
* The entity type.
* @param string $bundle
* The entity bundle.
- * @param string $schema_path
+ * @param string $schema_id
* The relative base path for the schema.
*
* @return \Symfony\Component\HttpFoundation\Response
@@ -50,7 +50,7 @@ public function setContainer(ContainerInterface $container = NULL) {
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
- public function bundle($entity_type, $bundle, $schema_path) {
+ public function bundle($entity_type, $bundle, $schema_id) {
if (!$entity_info = entity_get_info($entity_type)) {
throw new NotFoundHttpException(t('Entity type @entity_type not found', array('@entity_type' => $entity_type)));
}
@@ -60,7 +60,7 @@ public function bundle($entity_type, $bundle, $schema_path) {
$serializer = $this->container->get('serializer');
$site_schema_manager = $this->container->get('rdf.site_schema_manager');
- $schema = $site_schema_manager->getSchema($schema_path);
+ $schema = $site_schema_manager->getSchema($schema_id);
// @todo Remove hard-coded mimetype once we have proper conneg.
$content = $serializer->serialize($schema->bundle($entity_type, $bundle), 'jsonld');
return new Response($content, 200, array('Content-type' => 'application/json'));
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php
index d7afd1c..edc7c34 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php
@@ -28,6 +28,8 @@
*/
protected $siteSchema;
+ protected $configPrefix;
+
/**
* Constructor.
*
@@ -39,6 +41,17 @@ public function __construct($site_schema) {
}
/**
+ * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri().
+ */
+ function getUri() {
+ return url($this->getPath(), array('absolute' => TRUE));
+ }
+
+ public function getCurie() {
+ return $this->siteSchema->getPrefix() . ':' . $this->prepareUriPattern();
+ }
+
+ /**
* Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getProperties().
*/
public function getProperties() {
@@ -47,4 +60,26 @@ public function getProperties() {
);
}
+ public function getMappingConfig() {
+ $config_name = $this->getMappingConfigName();
+ $config = config($config_name);
+
+ // If the entity type isn't set, then the config didn't exist before and the
+ // config factory created a new config entity. Fill in the keys and save it.
+ $entity_type = $config->get('entity_type');
+ if (empty($entity_type)) {
+ $config->mid = $config_name;
+ foreach ($this->getMappingConfigKeys() as $key => $value) {
+ $config->set($key, $value);
+ }
+ $config->save();
+ }
+
+ return $config;
+ }
+
+ public function getMappingConfigName() {
+ return $this->configPrefix . '.' . implode(':', $this->getMappingConfigKeys());
+ }
+
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php
index 342b51e..239126e 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php
@@ -41,4 +41,15 @@ public function getProperties();
* The URI of the term.
*/
public function getUri();
+
+ /**
+ * Get the relative path of the term.
+ *
+ * Implementations of this method will use the URI patterns defined in
+ * $uriPattern static variables and replace placeholders with actual values.
+ *
+ * @return string
+ * The relative path of the term.
+ */
+ public function getPath();
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php
index e3153d1..dbb36d1 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php
@@ -19,8 +19,8 @@ class SiteSchema {
// are not intended to be extensible. If a site wants to use external
// vocabulary terms, the appropriate way to do this is to use the RDF mapping
// system.
- const CONTENT_DEPLOYMENT = 'site-schema/content-deployment/';
- const SYNDICATION = 'site-schema/syndication/';
+ const CONTENT_DEPLOYMENT = 'content-deployment';
+ const SYNDICATION = 'syndication';
/**
* The relative base path of the instantiated schema.
@@ -29,20 +29,26 @@ class SiteSchema {
*/
protected $schemaPath;
+ protected $schemaId;
+
+ protected $prefix;
+
/**
* Constructor.
*
- * @param string $schema_path
+ * @param string $schema_id
* The schema path constant, used to determine which schema to instantiate.
*
* @throws \UnexpectedValueException
*/
- public function __construct($schema_path) {
+ public function __construct($schema_id) {
$valid_paths = array(self::CONTENT_DEPLOYMENT, self::SYNDICATION);
- if (!in_array($schema_path, $valid_paths)) {
- throw new \UnexpectedValueException(sprintf('%s is not a valid site schema path. Schema path must be one of %s.'), $schema_path, implode(', ', $valid_paths));
+ if (!in_array($schema_id, $valid_paths)) {
+ throw new \UnexpectedValueException(sprintf('%s is not a valid site schema path. Schema path must be one of %s.'), $schema_id, implode(', ', $valid_paths));
}
- $this->schemaPath = $schema_path;
+ $this->schemaId = $schema_id;
+ $this->schemaPath = 'site-schema/' . $schema_id . '/';
+ $this->prefix = ($schema_id == self::CONTENT_DEPLOYMENT) ? 'site-cd' : 'site-syn';
}
/**
@@ -60,6 +66,13 @@ public function bundle($entity_type, $bundle) {
}
/**
+ * Get a field instance's term definition in this vocabulary.
+ */
+ public function field($entity_type, $bundle, $field_name) {
+ return new FieldSchema($this, $entity_type, $bundle, $field_name);
+ }
+
+ /**
* Get the URI of the schema.
*
* @return string
@@ -69,6 +82,10 @@ public function getUri() {
return url($this->schemaPath, array('absolute' => TRUE));
}
+ public function getId() {
+ return $this->schemaId;
+ }
+
/**
* Get the relative base path of the schema.
*/
@@ -76,6 +93,10 @@ public function getPath() {
return $this->schemaPath;
}
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
/**
* Get the routes for the types of terms defined in this schema.
*
diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php
index 7ca9ca8..6caa8fd 100644
--- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php
+++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php
@@ -65,8 +65,8 @@ public function getSchemas() {
return $this->siteSchemas;
}
- public function getSchema($schema_path) {
- return $this->siteSchemas[$schema_path];
+ public function getSchema($schema_id) {
+ return $this->siteSchemas[$schema_id];
}
/**
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php
index 3383f94..3fafc3b 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php
@@ -19,7 +19,7 @@ class CrudTest extends WebTestBase {
*
* @var array
*/
- public static $modules = array('rdf', 'rdf_test');
+ public static $modules = array('rdf', 'entity_test');
public static function getInfo() {
return array(
@@ -33,53 +33,54 @@ public static function getInfo() {
* Tests inserting, loading, updating, and deleting RDF mappings.
*/
function testCRUD() {
- // Verify loading of a default mapping.
- $mapping = _rdf_mapping_load('test_entity', 'test_bundle');
- $this->assertTrue(count($mapping), 'Default mapping was found.');
+ $entity_type = $bundle = 'entity_test';
+ $mapping_manager = drupal_container()->get('rdf.mapping_manager');
+ $bundle_mapping_config_name = "rdf.mapping.bundle.syndication:$entity_type:$bundle";
+ $user_id_mapping_config_name = "rdf.mapping.field.syndication:$entity_type:$bundle:user_id";
- // Verify saving a mapping.
- $mapping = array(
- 'type' => 'crud_test_entity',
- 'bundle' => 'crud_test_bundle',
- 'mapping' => array(
- 'rdftype' => array('sioc:Post'),
- 'title' => array(
- 'predicates' => array('dc:title'),
- ),
- 'uid' => array(
- 'predicates' => array('sioc:has_creator', 'dc:creator'),
- 'type' => 'rel',
- ),
- ),
- );
- $this->assertTrue(rdf_mapping_save($mapping) === SAVED_NEW, 'Mapping was saved.');
-
- // Read the raw record from the {rdf_mapping} table.
- $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle']));
- $stored_mapping = $result->fetchAssoc();
- $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']);
- $this->assertEqual($mapping, $stored_mapping, 'Mapping was stored properly in the {rdf_mapping} table.');
+ // Save bundle mapping config.
+ $bundle_mapping = $mapping_manager->getBundleMappingConfig($entity_type, $bundle);
+ $bundle_mapping->set('types', array('sioc:Post'))->save();
+ // Save field mapping config.
+ $user_id_mapping = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id');
+ $user_id_mapping->set('properties', array('sioc:has_creator', 'dc:creator'))->save();
- // Verify loading of saved mapping.
- $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.');
+ // Test that config files were saved.
+ $bundle_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.bundle');
+ $this->assertTrue(in_array($bundle_mapping_config_name, $bundle_mapping_configs), 'Bundle mapping config saved.');
+ $field_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.field');
+ $this->assertTrue(in_array($user_id_mapping_config_name, $field_mapping_configs), 'Field mapping config saved.');
- // Verify updating of mapping.
- $mapping['mapping']['title'] = array(
- 'predicates' => array('dc2:bar2'),
- );
- $this->assertTrue(rdf_mapping_save($mapping) === SAVED_UPDATED, 'Mapping was updated.');
+ // Test that config can be loaded.
+ $loaded_bundle_config = $mapping_manager->getBundleMappingConfig($entity_type, $bundle);
+ $bundle_config_array = $loaded_bundle_config->get();
+ $this->assertTrue(!empty($bundle_config_array), 'Bundle mapping config loaded.');
+ $loaded_field_config = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id');
+ $field_config_array = $loaded_field_config->get();
+ $this->assertTrue(!empty($field_config_array), 'Field mapping config loaded.');
- // Read the raw record from the {rdf_mapping} table.
- $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle']));
- $stored_mapping = $result->fetchAssoc();
- $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']);
- $this->assertEqual($mapping, $stored_mapping, 'Updated mapping was stored properly in the {rdf_mapping} table.');
+ // Test that the values were saved correctly.
+ $types = config($bundle_mapping_config_name)->get('types');
+ $this->assertTrue(in_array('sioc:Post', $types), 'Bundle mapping config values set properly.');
+ $properties = config($user_id_mapping_config_name)->get('properties');
+ $this->assertTrue(in_array('sioc:has_creator', $properties) && in_array('dc:creator', $properties), 'Field mapping config values set properly.');
- // Verify loading of saved mapping.
- $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.');
+ // Test that mapping can be updated.
+ $bundle_mapping->set('types', array('schema:Thing'))->save();
+ $loaded_bundle_config = $mapping_manager->getBundleMappingConfig($entity_type, $bundle);
+ $types = $loaded_bundle_config->get('types');
+ $this->assert(in_array('schema:Thing', $types) && !in_array('sioc:Post', $types), 'Bundle mapping was updated.');
+ $user_id_mapping->set('properties', array('schema:author'))->save();
+ $loaded_config = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id');
+ $properties = $loaded_config->get('properties');
+ $this->assert(in_array('schema:author', $properties) && !in_array('sioc:has_creator', $properties), 'Field mapping was updated.');
- // Verify deleting of mapping.
- $this->assertTrue(rdf_mapping_delete($mapping['type'], $mapping['bundle']), 'Mapping was deleted.');
- $this->assertFalse(_rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Deleted mapping is no longer found in the database.');
+ // Test that the mapping can be deleted.
+ $bundle_mapping->delete();
+ $bundle_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.bundle');
+ $this->assertFalse(in_array($bundle_mapping_config_name, $bundle_mapping_configs), 'Bundle mapping config deleted.');
+ $user_id_mapping->delete();
+ $field_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.field');
+ $this->assertFalse(in_array($user_id_mapping_config_name, $field_mapping_configs), 'Field mapping config deleted.');
}
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php
index 0cfe07f..b8d20ce 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php
@@ -44,7 +44,7 @@ function testSiteSchema() {
$bundle_uri = url("$schema_path$entity_type/$bundle", array('absolute' => TRUE));
$bundle_properties = array(
'http://www.w3.org/2000/01/rdf-schema#isDefinedBy' => url($schema_path, array('absolute' => TRUE)),
- 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => 'http://www.w3.org/2000/01/rdf-schema#class',
+ 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => 'http://www.w3.org/2000/01/rdf-schema#Class',
'http://www.w3.org/2000/01/rdf-schema#subClassOf' => url("$schema_path$entity_type", array('absolute' => TRUE)),
);
diff --git a/core/modules/rdf/rdf.install b/core/modules/rdf/rdf.install
index 10d3f8d..be2cde1 100644
--- a/core/modules/rdf/rdf.install
+++ b/core/modules/rdf/rdf.install
@@ -4,46 +4,3 @@
* @file
* Install, update and uninstall functions for the rdf module.
*/
-
-/**
- * Implements hook_schema().
- */
-function rdf_schema() {
- $schema['rdf_mapping'] = array(
- 'description' => 'Stores custom RDF mappings for user defined content types or overriden module-defined mappings',
- 'fields' => array(
- 'type' => array(
- 'type' => 'varchar',
- 'length' => 128,
- 'not null' => TRUE,
- 'description' => 'The name of the entity type a mapping applies to (node, user, comment, etc.).',
- ),
- 'bundle' => array(
- 'type' => 'varchar',
- 'length' => 128,
- 'not null' => TRUE,
- 'description' => 'The name of the bundle a mapping applies to.',
- ),
- 'mapping' => array(
- 'description' => 'The serialized mapping of the bundle type and fields to RDF terms.',
- 'type' => 'blob',
- 'not null' => FALSE,
- 'size' => 'big',
- 'serialize' => TRUE,
- ),
- ),
- 'primary key' => array('type', 'bundle'),
- );
-
- return $schema;
-}
-
-/**
- * Implements hook_install().
- */
-function rdf_install() {
- // Collect any RDF mappings that were declared by modules installed before
- // this one.
- $modules = module_implements('rdf_mapping');
- rdf_modules_installed($modules);
-}
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 264a090..2cf869c 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -128,100 +128,34 @@ function rdf_get_namespaces() {
* @param $type
* An entity type.
* @param $bundle
- * (optional) A bundle name.
+ * A bundle name.
*
* @return
* The mapping corresponding to the requested entity type/bundle pair or an
* empty array.
*/
-function rdf_mapping_load($type, $bundle = RDF_DEFAULT_BUNDLE) {
- // Retrieves the bundle-specific mapping from the entity info.
- $entity_info = entity_get_info($type);
- if (!empty($entity_info['bundles'][$bundle]['rdf_mapping'])) {
- return $entity_info['bundles'][$bundle]['rdf_mapping'];
- }
- // If there is no mapping defined for this bundle, we return the default
- // mapping that is defined for this entity type.
- else {
- return _rdf_get_default_mapping($type);
- }
-}
-
-/**
- * @} End of "defgroup rdf".
- */
-
-/**
- * Gets the default RDF mapping for a given entity type.
- *
- * @param $type
- * An entity type, e.g. 'node' or 'comment'.
- *
- * @return
- * The RDF mapping or an empty array if no mapping is defined for this entity
- * type.
- */
-function _rdf_get_default_mapping($type) {
- $default_mappings = &drupal_static(__FUNCTION__);
-
- if (!isset($default_mappings)) {
- // Get all of the modules that implement hook_rdf_mapping().
- $modules = module_implements('rdf_mapping');
-
- // Only consider the default entity mapping definitions.
- foreach ($modules as $module) {
- $mappings = module_invoke($module, 'rdf_mapping');
- foreach ($mappings as $mapping) {
- if ($mapping['bundle'] === RDF_DEFAULT_BUNDLE) {
- $default_mappings[$mapping['type']] = $mapping['mapping'];
- }
+function rdf_mapping_load($type, $bundle) {
+ $mapping_manager = drupal_container()->get('rdf.mapping_manager');
+ $mapping = array(
+ 'rdftypes' => $mapping_manager->getBundleMapping($type, $bundle),
+ );
+ $entity = entity_create($type, array('type' => $bundle));
+
+ $properties = $entity->getPropertyDefinitions();
+ if (!empty($properties)) {
+ foreach ($properties as $field_name => $field_info) {
+ $field_mapping = $mapping_manager->getFieldMapping($type, $bundle, $field_name);
+ if (!empty($field_mapping)) {
+ $mapping[$field_name] = $field_mapping;
}
}
}
-
- return isset($default_mappings[$type]) ? $default_mappings[$type] : array();
+ return $mapping;
}
/**
- * Retrieves an RDF mapping from the database.
- *
- * @param $type
- * The entity type the mapping refers to.
- * @param $bundle
- * The bundle the mapping refers to.
- *
- * @return
- * An RDF mapping structure or, FALSE if the mapping does not exist.
- */
-function _rdf_mapping_load($type, $bundle) {
- $mappings = _rdf_mapping_load_multiple($type, array($bundle));
- return $mappings ? reset($mappings) : FALSE;
-}
-
-/**
- * Helper function to retrieve a set of RDF mappings from the database.
- *
- * @param $type
- * The entity type of the mappings.
- * @param $bundles
- * The bundles the mappings refer to.
- *
- * @return
- * An array of RDF mapping structures, or an empty array.
+ * @} End of "defgroup rdf".
*/
-function _rdf_mapping_load_multiple($type, array $bundles) {
- $mappings = db_select('rdf_mapping')
- ->fields(NULL, array('bundle', 'mapping'))
- ->condition('type', $type)
- ->condition('bundle', $bundles)
- ->execute()
- ->fetchAllKeyed();
-
- foreach ($mappings as $bundle => $mapping) {
- $mappings[$bundle] = unserialize($mapping);
- }
- return $mappings;
-}
/**
* @addtogroup rdf
@@ -229,61 +163,6 @@ function _rdf_mapping_load_multiple($type, array $bundles) {
*/
/**
- * Saves an RDF mapping to the database.
- *
- * Takes a mapping structure returned by hook_rdf_mapping() implementations
- * and creates or updates a record mapping for each encountered entity
- * type/bundle pair. If available, adds default values for non-existent mapping
- * keys.
- *
- * @param $mapping
- * The RDF mapping to save.
- *
- * @return
- * MergeQuery object that indicates the outcome of the operation.
- */
-function rdf_mapping_save($mapping) {
- // In the case where a field has a mapping defined in the default entity
- // mapping, but a mapping is not specified in the bundle-specific mapping,
- // then use the default mapping for that field.
- $mapping['mapping'] += _rdf_get_default_mapping($mapping['type']);
-
- $status = db_merge('rdf_mapping')
- ->key(array(
- 'type' => $mapping['type'],
- 'bundle' => $mapping['bundle'],
- ))
- ->fields(array(
- 'mapping' => serialize($mapping['mapping']),
- ))
- ->execute();
-
- entity_info_cache_clear();
-
- return $status;
-}
-
-/**
- * Deletes the mapping for the given bundle from the database.
- *
- * @param $type
- * The entity type the mapping refers to.
- * @param $bundle
- * The bundle the mapping refers to.
- *
- * @return
- * TRUE if the mapping is deleted, FALSE if not.
- */
-function rdf_mapping_delete($type, $bundle) {
- $num_rows = db_delete('rdf_mapping')
- ->condition('type', $type)
- ->condition('bundle', $bundle)
- ->execute();
-
- return (bool) ($num_rows > 0);
-}
-
-/**
* Builds an array of RDFa attributes for a given mapping.
*
* This array will typically be passed through Drupal\Core\Template\Attribute
@@ -345,98 +224,6 @@ function rdf_rdfa_attributes($mapping, $data = NULL) {
*/
/**
- * Implements hook_modules_installed().
- *
- * Checks if the installed modules have any RDF mapping definitions to declare
- * and stores them in the rdf_mapping table.
- *
- * While both default entity mappings and specific bundle mappings can be
- * defined in hook_rdf_mapping(), default entity mappings are not stored in the
- * database. Only overridden mappings are stored in the database. The default
- * entity mappings can be overriden by specific bundle mappings which are
- * stored in the database and can be altered via the RDF CRUD mapping API.
- */
-function rdf_modules_installed($modules) {
- foreach ($modules as $module) {
- $function = $module . '_rdf_mapping';
- if (function_exists($function)) {
- foreach ($function() as $mapping) {
- // Only the bundle mappings are saved in the database.
- if ($mapping['bundle'] !== RDF_DEFAULT_BUNDLE) {
- rdf_mapping_save($mapping);
- }
- }
- }
- }
-}
-
-/**
- * Implements hook_modules_uninstalled().
- */
-function rdf_modules_uninstalled($modules) {
- // @todo Remove RDF mappings of uninstalled modules.
-}
-
-/**
- * Implements hook_entity_info_alter().
- *
- * Adds the proper RDF mapping to each entity type/bundle pair.
- *
- * @todo May need to move the comment below to another place.
- * This hook should not be used by modules to alter the bundle mappings. The UI
- * should always be authoritative. UI mappings are stored in the database and
- * if hook_entity_info_alter() was used to override module defined mappings, it
- * would override the user defined mapping as well.
- *
- */
-function rdf_entity_info_alter(&$entity_info) {
- // Loop through each entity type and its bundles.
- foreach ($entity_info as $entity_type => $entity_type_info) {
- if (!empty($entity_type_info['bundles'])) {
- $bundles = array_keys($entity_type_info['bundles']);
- $mappings = _rdf_mapping_load_multiple($entity_type, $bundles);
-
- foreach ($bundles as $bundle) {
- if (isset($mappings[$bundle])) {
- $entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = $mappings[$bundle];
- }
- else {
- // If no mapping was found in the database, assign the default RDF
- // mapping for this entity type.
- $entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = _rdf_get_default_mapping($entity_type);
- }
- }
- }
- }
-}
-
-/**
- * Implements hook_entity_load().
- */
-function rdf_entity_load($entities, $type) {
- foreach ($entities as $entity) {
- // Extracts the bundle of the entity being loaded.
- $entity->rdf_mapping = rdf_mapping_load($type, $entity->bundle());
- }
-}
-
-/**
- * Implements hook_comment_load().
- */
-function rdf_comment_load($comments) {
- foreach ($comments as $comment) {
- // Pages with many comments can show poor performance. This information
- // isn't needed until rdf_preprocess_comment() is called, but set it here
- // to optimize performance for websites that implement an entity cache.
- $comment->rdf_data['date'] = rdf_rdfa_attributes($comment->rdf_mapping['created'], $comment->created);
- $comment->rdf_data['nid_uri'] = url('node/' . $comment->nid);
- if ($comment->pid) {
- $comment->rdf_data['pid_uri'] = url('comment/' . $comment->pid, array('fragment' => 'comment-' . $comment->pid));
- }
- }
-}
-
-/**
* Implements hook_theme().
*/
function rdf_theme() {
@@ -511,14 +298,17 @@ function rdf_preprocess_node(&$variables) {
// URI of the resource described within the HTML element, while the @typeof
// attribute indicates its RDF type (e.g., foaf:Document, sioc:Person, and so
// on.)
+ $mapping_manager = drupal_container()->get('rdf.mapping_manager');
+ $bundle_mapping = $mapping_manager->getBundleMapping('node', $variables['type']);
$variables['attributes']['about'] = empty($variables['node_url']) ? NULL: $variables['node_url'];
- $variables['attributes']['typeof'] = empty($variables['node']->rdf_mapping['rdftype']) ? NULL : $variables['node']->rdf_mapping['rdftype'];
+ $variables['attributes']['typeof'] = empty($bundle_mapping['rdftype']) ? NULL : $bundle_mapping['rdftype'];
// Adds RDFa markup to the title of the node. Because the RDFa markup is
// added to the
tag which might contain HTML code, we specify an empty
// datatype to ensure the value of the title read by the RDFa parsers is a
// literal.
- $variables['title_attributes']['property'] = empty($variables['node']->rdf_mapping['title']['predicates']) ? NULL : $variables['node']->rdf_mapping['title']['predicates'];
+ $title_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'title');
+ $variables['title_attributes']['property'] = empty($title_mapping['predicates']) ? NULL : $title_mapping['predicates'];
$variables['title_attributes']['datatype'] = '';
// In full node mode, the title is not displayed by node.tpl.php so it is
@@ -531,35 +321,38 @@ function rdf_preprocess_node(&$variables) {
'about' => $variables['node_url'],
),
);
- if (!empty($variables['node']->rdf_mapping['title']['predicates'])) {
- $element['#attributes']['property'] = $variables['node']->rdf_mapping['title']['predicates'];
+ if (!empty($title_mapping['predicates'])) {
+ $element['#attributes']['property'] = $title_mapping['predicates'];
}
drupal_add_html_head($element, 'rdf_node_title');
}
// Adds RDFa markup for the date.
- if (!empty($variables['node']->rdf_mapping['created'])) {
- $date_attributes = rdf_rdfa_attributes($variables['node']->rdf_mapping['created'], $variables['node']->created);
+ $created_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'created');
+ if (!empty($created_mapping)) {
+ $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->created);
$variables['rdf_template_variable_attributes']['date'] = $date_attributes;
if ($variables['submitted']) {
$variables['rdf_template_variable_attributes']['submitted'] = $date_attributes;
}
}
// Adds RDFa markup for the relation between the node and its author.
- if (!empty($variables['node']->rdf_mapping['uid'])) {
- $variables['rdf_template_variable_attributes']['name']['rel'] = $variables['node']->rdf_mapping['uid']['predicates'];
+ $uid_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'uid');
+ if (!empty($uid_mapping)) {
+ $variables['rdf_template_variable_attributes']['name']['rel'] = $uid_mapping['predicates'];
if ($variables['submitted']) {
- $variables['rdf_template_variable_attributes']['submitted']['rel'] = $variables['node']->rdf_mapping['uid']['predicates'];
+ $variables['rdf_template_variable_attributes']['submitted']['rel'] = $uid_mapping['predicates'];
}
}
// Adds RDFa markup annotating the number of comments a node has.
- if (isset($variables['node']->comment_count) && !empty($variables['node']->rdf_mapping['comment_count']['predicates'])) {
+ $comment_count_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'comment_count');
+ if (isset($variables['node']->comment_count) && !empty($comment_count_mapping['predicates'])) {
// Annotates the 'x comments' link in teaser view.
if (isset($variables['content']['links']['comment']['#links']['comment-comments'])) {
- $comment_count_attributes['property'] = $variables['node']->rdf_mapping['comment_count']['predicates'];
+ $comment_count_attributes['property'] = $comment_count_mapping['predicates'];
$comment_count_attributes['content'] = $variables['node']->comment_count;
- $comment_count_attributes['datatype'] = $variables['node']->rdf_mapping['comment_count']['datatype'];
+ $comment_count_attributes['datatype'] = $comment_count_mapping['datatype'];
// According to RDFa parsing rule number 4, a new subject URI is created
// from the href attribute if no rel/rev attribute is present. To get the
// original node URL from the about attribute of the parent container we
@@ -576,9 +369,9 @@ function rdf_preprocess_node(&$variables) {
'#tag' => 'meta',
'#attributes' => array(
'about' => $variables['node_url'],
- 'property' => $variables['node']->rdf_mapping['comment_count']['predicates'],
+ 'property' => $comment_count_mapping['predicates'],
'content' => $variables['node']->comment_count,
- 'datatype' => $variables['node']->rdf_mapping['comment_count']['datatype'],
+ 'datatype' => isset($comment_count_mapping['datatype']) ? $comment_count_mapping['datatype'] : NULL,
),
);
drupal_add_html_head($element, 'rdf_node_comment_count');
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 48da6b1..2325c14 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -218,34 +218,6 @@ function standard_install() {
node_add_body_field($type);
}
- // Insert default pre-defined RDF mapping into the database.
- $rdf_mappings = array(
- array(
- 'type' => 'node',
- 'bundle' => 'page',
- 'mapping' => array(
- 'rdftype' => array('foaf:Document'),
- ),
- ),
- array(
- 'type' => 'node',
- 'bundle' => 'article',
- 'mapping' => array(
- 'field_image' => array(
- 'predicates' => array('og:image', 'rdfs:seeAlso'),
- 'type' => 'rel',
- ),
- 'field_tags' => array(
- 'predicates' => array('dc:subject'),
- 'type' => 'rel',
- ),
- ),
- ),
- );
- foreach ($rdf_mappings as $rdf_mapping) {
- rdf_mapping_save($rdf_mapping);
- }
-
// Default "Basic page" to not be promoted and have comments disabled.
variable_set('node_options_page', array('status'));
variable_set('comment_page', COMMENT_NODE_HIDDEN);
@@ -432,4 +404,75 @@ function standard_install() {
theme_enable(array('seven'));
config('system.theme')->set('admin', 'seven')->save();
variable_set('node_admin_theme', '1');
+
+ // Save the RDF mapping configuration.
+ $rdf_mapping_manager = drupal_container()->get('rdf.mapping_manager');
+ $bundle_mapping = array(
+ 'types' => array('foaf:Document', 'sioc:Item'),
+ );
+ $shared_field_mappings = array(
+ 'title' => array(
+ 'properties' => array('dc:title'),
+ ),
+ 'created' => array(
+ 'properties' => array('dc:date', 'dc:created'),
+ 'datatype' => 'xsd:dateTime',
+ 'datatype_callback' => 'date_iso8601',
+ ),
+ 'changed' => array(
+ 'properties' => array('dc:modified'),
+ 'datatype' => 'xsd:dateTime',
+ 'datatype_callback' => 'date_iso8601',
+ ),
+ 'body' => array(
+ 'properties' => array('content:encoded'),
+ ),
+ 'uid' => array(
+ 'properties' => array('sioc:has_creator'),
+ 'type' => 'rel',
+ ),
+ 'name' => array(
+ 'properties' => array('foaf:name'),
+ ),
+ 'comment_count' => array(
+ 'properties' => array('sioc:num_replies'),
+ 'datatype' => 'xsd:integer',
+ ),
+ 'last_activity' => array(
+ 'properties' => array('sioc:last_activity_date'),
+ 'datatype' => 'xsd:dateTime',
+ 'datatype_callback' => 'date_iso8601',
+ ),
+ );
+ // Save the bundle mapping and shared field mappings for both node bundles.
+ foreach (array('article', 'page') as $bundle) {
+ // Save bundle mapping config.
+ $config = $rdf_mapping_manager->getBundleMappingConfig('node', $bundle);
+ $bundle_mapping = array_merge($config->get(), $bundle_mapping);
+ $config->setData($bundle_mapping)->save();
+ // Iterate over shared field mappings and save.
+ foreach ($shared_field_mappings as $field_name => $field_mapping) {
+ $config = $rdf_mapping_manager->getFieldMappingConfig('node', $bundle, $field_name);
+ $field_mapping = array_merge($config->get(), $field_mapping);
+ $config->setData($field_mapping)->save();
+ }
+ }
+
+ // Save the RDF mappings for fields which are unique to articles.
+ $field_image_mapping = array(
+ 'properties' => array('og:image', 'rdfs:seeAlso'),
+ 'type' => 'rel',
+ );
+ $field_tags_mapping = array(
+ 'properties' => array('dc:subject'),
+ 'type' => 'rel',
+ );
+ // Save field_image mapping.
+ $config = $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_image');
+ $field_mapping = array_merge($config->get(), $field_image_mapping);
+ $config->setData($field_mapping)->save();
+ // Save field_tags mapping.
+ $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_tags');
+ $field_mapping = array_merge($config->get(), $field_tags_mapping);
+ $config->setData($field_mapping)->save();
}
diff --git a/index.php b/index.php
index 98bcddb..53c6199 100644
--- a/index.php
+++ b/index.php
@@ -37,6 +37,7 @@
// Create a request object from the HTTPFoundation.
$request = Request::createFromGlobals();
+$mapping = rdf_mapping_load('node', 'article');
$response = $kernel->handle($request)->prepare($request)->send();
$kernel->terminate($request, $response);