DLynch has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/303956

Change subject: LinkAnnotationInspector: add a "label" field
......................................................................

LinkAnnotationInspector: add a "label" field

This field will allow the link text to be edited inside the inspector. If left
empty, the current behavior of generating link text from the href will be
followed. If the current value of the label contains anything which isn't
text, the input will be disabled and its value ignored on teardown.

Bug: T55973
Change-Id: Ic5fbbf3629e92d933fda61969615ff5262437e07
---
M i18n/en.json
M i18n/qqq.json
M src/dm/lineardata/ve.dm.ElementLinearData.js
M src/dm/ve.dm.SurfaceFragment.js
M src/ui/inspectors/ve.ui.AnnotationInspector.js
M src/ui/inspectors/ve.ui.LinkAnnotationInspector.js
M src/ui/widgets/ve.ui.LinkAnnotationWidget.js
7 files changed, 87 insertions(+), 21 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/56/303956/1

diff --git a/i18n/en.json b/i18n/en.json
index 0e45b8a..a521fb2 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -98,6 +98,8 @@
        "visualeditor-languageinspector-widget-label-direction": "Direction",
        "visualeditor-languageinspector-widget-label-langcode": "Language code",
        "visualeditor-languageinspector-widget-label-language": "Language",
+       "visualeditor-linkinspector-label": "Label",
+       "visualeditor-linkinspector-target": "Target",
        "visualeditor-linkinspector-title": "Link",
        "visualeditor-listbutton-bullet-tooltip": "Bullet list",
        "visualeditor-listbutton-number-tooltip": "Numbered list",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 2ff56ed..4a9b993 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -106,6 +106,8 @@
        "visualeditor-languageinspector-widget-label-direction": "Label for the 
language inspector widget, to denote the text direction of the current element 
(left-to-right or right-to-left).\n{{Identical|Direction}}",
        "visualeditor-languageinspector-widget-label-langcode": "Label for the 
language inspector widget, to denote the current block language 
code.\n{{Identical|Language code}}",
        "visualeditor-languageinspector-widget-label-language": "Label for the 
language inspector widget, to denote the current block 
language.\n{{Identical|Language}}",
+       "visualeditor-linkinspector-label": "Label for the label field of the 
link inspector dialog",
+       "visualeditor-linkinspector-target": "Label for the target field of the 
link inspector dialog",
        "visualeditor-linkinspector-title": "Title of the link inspector 
dialog.\n{{Identical|Link}}",
        "visualeditor-listbutton-bullet-tooltip": "Tooltip text for the bullet 
list button",
        "visualeditor-listbutton-number-tooltip": "Tooltip text for the 
numbered list button",
diff --git a/src/dm/lineardata/ve.dm.ElementLinearData.js 
b/src/dm/lineardata/ve.dm.ElementLinearData.js
index 261c3c6..8becf23 100644
--- a/src/dm/lineardata/ve.dm.ElementLinearData.js
+++ b/src/dm/lineardata/ve.dm.ElementLinearData.js
@@ -615,14 +615,15 @@
 };
 
 /**
- * Check if the data is just plain (un-annotated) text
+ * Check if the data is just text
  *
  * @param {ve.Range} [range] Range to get the data for. The whole data set if 
not specified.
- * @param {boolean} [allowNonContentNodes] Include non-content nodes in the 
definition of plain text, e.g. paragraphs, headings, lists
- * @param {boolean} [allowedTypes] Only allow specific non-content types
- * @return {boolean} The data is plain text
+ * @param {boolean} [allowAnnotations] Include annotated text in the 
definition of plain text, e.g. paragraphs, headings, lists
+ * @param {boolean} [allowNonContentNodes] Include non-content nodes in the 
definition of text, e.g. paragraphs, headings, lists
+ * @param {Array} [allowedTypes] Allow specific non-content types included in 
this array
+ * @return {boolean} The data is text
  */
-ve.dm.ElementLinearData.prototype.isPlainText = function ( range, 
allowNonContentNodes, allowedTypes ) {
+ve.dm.ElementLinearData.prototype.isText = function ( range, allowAnnotations, 
allowNonContentNodes, allowedTypes ) {
        var i, type;
 
        range = range || new ve.Range( 0, this.getLength() );
@@ -630,23 +631,38 @@
        for ( i = range.start; i < range.end; i++ ) {
                if ( typeof this.data[ i ] === 'string' ) {
                        continue;
-               } else if ( ( allowNonContentNodes || allowedTypes ) && 
this.isElementData( i ) ) {
-                       type = this.getType( i );
-                       if ( allowedTypes && allowedTypes.indexOf( type ) !== 
-1 ) {
-                               continue;
-                       }
-                       if ( allowNonContentNodes && 
!ve.dm.nodeFactory.isNodeContent( type ) ) {
-                               continue;
+               } else if ( this.isElementData( i ) ) {
+                       if ( ( allowNonContentNodes || allowedTypes ) ) {
+                               type = this.getType( i );
+                               if ( allowedTypes && allowedTypes.indexOf( type 
) !== -1 ) {
+                                       continue;
+                               }
+                               if ( allowNonContentNodes && 
!ve.dm.nodeFactory.isNodeContent( type ) ) {
+                                       continue;
+                               }
                        }
                        return false;
-               } else {
-                       return false;
+               } else if ( allowAnnotations && this.data[ i ].length ) {
+                       continue;
                }
+               return false;
        }
        return true;
 };
 
 /**
+ * Check if the data is just plain (un-annotated) text
+ *
+ * @param {ve.Range} [range] Range to get the data for. The whole data set if 
not specified.
+ * @param {boolean} [allowNonContentNodes] Include non-content nodes in the 
definition of plain text, e.g. paragraphs, headings, lists
+ * @param {Array} [allowedTypes] Allow specific non-content types included in 
this array
+ * @return {boolean} The data is plain text
+ */
+ve.dm.ElementLinearData.prototype.isPlainText = function ( range, 
allowNonContentNodes, allowedTypes ) {
+       return this.isText( range, false, allowNonContentNodes, allowedTypes );
+};
+
+/**
  * Get the data as plain text
  *
  * @param {boolean} [maintainIndices] Maintain data offset to string index 
alignment by replacing elements with line breaks
diff --git a/src/dm/ve.dm.SurfaceFragment.js b/src/dm/ve.dm.SurfaceFragment.js
index 8a2fd5f..7fd24fd 100644
--- a/src/dm/ve.dm.SurfaceFragment.js
+++ b/src/dm/ve.dm.SurfaceFragment.js
@@ -445,6 +445,20 @@
 };
 
 /**
+ * Whether the fragment contains only text, allowing annotations
+ *
+ * @method
+ * @return {boolean} Whether there's only text
+ */
+ve.dm.SurfaceFragment.prototype.containsOnlyText = function () {
+       var range = this.getSelection().getCoveringRange();
+       if ( !range ) {
+               return true;
+       }
+       return this.document.data.isText( range, true );
+};
+
+/**
  * Get annotations in fragment.
  *
  * By default, this will only get annotations that completely cover the 
fragment. Use the {all}
diff --git a/src/ui/inspectors/ve.ui.AnnotationInspector.js 
b/src/ui/inspectors/ve.ui.AnnotationInspector.js
index 774999c..6cd3f4e 100644
--- a/src/ui/inspectors/ve.ui.AnnotationInspector.js
+++ b/src/ui/inspectors/ve.ui.AnnotationInspector.js
@@ -77,6 +77,19 @@
 };
 
 /**
+ * Work out whether the teardown process should replace the current text of 
the fragment.
+ *
+ * Default behavior is to only do so if nothing was selected initially, in 
which case we
+ * need *something* to apply the annotation to. If this returns true, 
getInsertionData had
+ * better produce something.
+ *
+ * @return {boolean} Whether to insert text on teardown
+ */
+ve.ui.AnnotationInspector.prototype.shouldInsertText = function () {
+       return this.initialSelection.isCollapsed();
+};
+
+/**
  * Get data to insert if nothing was selected when the inspector opened.
  *
  * Defaults to using #getInsertionText.
@@ -274,9 +287,7 @@
                                        surfaceModel.setSelection( 
this.previousSelection );
                                        return;
                                }
-                               if ( this.initialSelection.isCollapsed() ) {
-                                       insertText = true;
-                               }
+                               insertText = this.shouldInsertText();
                                if ( annotation ) {
                                        // Check if the initial annotation has 
changed, or didn't cover the whole fragment
                                        // to begin with
diff --git a/src/ui/inspectors/ve.ui.LinkAnnotationInspector.js 
b/src/ui/inspectors/ve.ui.LinkAnnotationInspector.js
index 9a5fbeb..e161ee8 100644
--- a/src/ui/inspectors/ve.ui.LinkAnnotationInspector.js
+++ b/src/ui/inspectors/ve.ui.LinkAnnotationInspector.js
@@ -68,7 +68,7 @@
  * @inheritdoc
  */
 ve.ui.LinkAnnotationInspector.prototype.getInsertionText = function () {
-       return this.annotationInput.getHref();
+       return this.labelInput.getValue().trim() || 
this.annotationInput.getHref();
 };
 
 /**
@@ -86,7 +86,7 @@
 
        return text ? new ve.dm.LinkAnnotation( {
                type: 'link',
-               attributes: { href: fragment.getText() }
+               attributes: { href: text }
        } ) : null;
 };
 
@@ -98,13 +98,24 @@
        ve.ui.LinkAnnotationInspector.super.prototype.initialize.call( this );
 
        // Properties
+       this.labelInput = this.createLabelInput();
        this.annotationInput = this.createAnnotationInput();
 
        // Events
        this.annotationInput.connect( this, { change: 'onAnnotationInputChange' 
} );
 
        // Initialization
+       this.form.$element.append( this.labelInput.$element );
        this.form.$element.append( this.annotationInput.$element );
+};
+
+/**
+ * Create a link label widget
+ *
+ * @return {OO.ui.TextInputWidget} Link label widget
+ */
+ve.ui.LinkAnnotationInspector.prototype.createLabelInput = function () {
+       return new OO.ui.TextInputWidget( { label: OO.ui.deferMsg( 
'visualeditor-linkinspector-label' ) } );
 };
 
 /**
@@ -119,11 +130,21 @@
 /**
  * @inheritdoc
  */
+ve.ui.LinkAnnotationInspector.prototype.shouldInsertText = function () {
+       return 
ve.ui.LinkAnnotationInspector.super.prototype.shouldInsertText.call( this ) || 
!this.labelInput.isDisabled();
+};
+
+/**
+ * @inheritdoc
+ */
 ve.ui.LinkAnnotationInspector.prototype.getSetupProcess = function ( data ) {
        return 
ve.ui.LinkAnnotationInspector.super.prototype.getSetupProcess.call( this, data )
                .next( function () {
+                       var fragment = this.getFragment();
                        // Disable surface until animation is complete; will be 
reenabled in ready()
-                       this.getFragment().getSurface().disable();
+                       fragment.getSurface().disable();
+                       this.labelInput.setDisabled( 
!fragment.containsOnlyText() );
+                       this.labelInput.setValue( fragment.getText() );
                        this.annotationInput.setAnnotation( 
this.initialAnnotation );
                        this.updateActions();
                }, this );
diff --git a/src/ui/widgets/ve.ui.LinkAnnotationWidget.js 
b/src/ui/widgets/ve.ui.LinkAnnotationWidget.js
index 42b8271..5cec04d 100644
--- a/src/ui/widgets/ve.ui.LinkAnnotationWidget.js
+++ b/src/ui/widgets/ve.ui.LinkAnnotationWidget.js
@@ -89,7 +89,7 @@
  * @return {OO.ui.Widget} Text input widget
  */
 ve.ui.LinkAnnotationWidget.prototype.createInputWidget = function ( config ) {
-       return new OO.ui.TextInputWidget( $.extend( { validate: 'non-empty' }, 
config ) );
+       return new OO.ui.TextInputWidget( $.extend( { label: OO.ui.deferMsg( 
'visualeditor-linkinspector-target' ), icon: 'link', validate: 'non-empty' }, 
config ) );
 };
 
 /**

-- 
To view, visit https://gerrit.wikimedia.org/r/303956
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic5fbbf3629e92d933fda61969615ff5262437e07
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: DLynch <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to