Jsahleen has uploaded a new change for review.
https://gerrit.wikimedia.org/r/181374
Change subject: [WIP] Red Links: Adding red link functionality
......................................................................
[WIP] Red Links: Adding red link functionality
* Red links are marked with grey and dashed underline
* Clicking on marker brings up "Mark link" option
* After being marked as missing links, can be reverted.
* Improvements to isValidSelection to prevent links inside links
* Note: Significant refactoring was necessary to make this work.
Change-Id: I6bce4bdd4688a5fb20c3268561329b126e57c3c7
---
M Resources.php
M i18n/en.json
M i18n/qqq.json
M modules/publish/ext.cx.publish.js
M modules/tools/ext.cx.tools.link.js
M modules/tools/styles/ext.cx.tools.link.less
6 files changed, 427 insertions(+), 116 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ContentTranslation
refs/changes/74/181374/1
diff --git a/Resources.php b/Resources.php
index f758a3f..682c039 100644
--- a/Resources.php
+++ b/Resources.php
@@ -347,6 +347,10 @@
'cx-tools-link-add',
'cx-tools-link-remove',
'cx-tools-link-instruction-shortcut',
+ 'cx-tools-missing-link-title',
+ 'cx-tools-missing-link-text',
+ 'cx-tools-missing-link-tooltip',
+ 'cx-tools-missing-link-mark-link'
),
'dependencies' => array(
'ext.cx.tools.manager',
diff --git a/i18n/en.json b/i18n/en.json
index e66d5e2..bc833a9 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -122,5 +122,9 @@
"cx-save-draft-tooltip": "Translation drafts are saved automatically",
"cx-contributions": "New contribution",
"cx-contributions-translation": "Translation",
- "cx-contributions-media": "Upload media file"
+ "cx-contributions-media": "Upload media file",
+ "cx-tools-missing-link-title": "Missing link",
+ "cx-tools-missing-link-text": "Mark missing pages to encourage their
creation",
+ "cx-tools-missing-link-tooltip": "Translate (in new window)",
+ "cx-tools-missing-link-mark-link": "Mark as missing"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 17b2cb5..1efd8f6 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -125,5 +125,9 @@
"cx-save-draft-tooltip": "Tooltip text shown for the save status
indicator text in the header of [[Special:ContentTranslation]].\n\nParameters:
\n* $1 - the number of minutes ago the translation was saved.",
"cx-contributions": "Text of a button which opens a dropdown",
"cx-contributions-translation": "Dropdown
item\n{{Identical|Translation}}",
- "cx-contributions-media": "Dropdown item"
+ "cx-contributions-media": "Dropdown item",
+ "cx-tools-missing-link-title": "Title for target link card when card is
used for working with missing links",
+ "cx-tools-missing-link-text": "Message with instructions for marking
links as missing",
+ "cx-tools-missing-link-tooltip": "Tooltip that shows when hovering over
target link card link when working with missing links.\nClicking on link opens
a new translation view for the missing link.",
+ "cx-tools-missing-link-mark-link": "Text for mark as missing link
control"
}
diff --git a/modules/publish/ext.cx.publish.js
b/modules/publish/ext.cx.publish.js
index 00ca9c7..05c16d0 100644
--- a/modules/publish/ext.cx.publish.js
+++ b/modules/publish/ext.cx.publish.js
@@ -196,6 +196,9 @@
}
} );
+ // Remove any remaining red link markers
+ $content.find( '.cx-redlink-marker' ).remove();
+
return $content.html();
}
diff --git a/modules/tools/ext.cx.tools.link.js
b/modules/tools/ext.cx.tools.link.js
index ad93c46..f3df7d4 100644
--- a/modules/tools/ext.cx.tools.link.js
+++ b/modules/tools/ext.cx.tools.link.js
@@ -21,9 +21,11 @@
this.$card = null;
this.$removeLink = null;
this.$addLink = null;
+ this.$markLink = null;
this.$link = null;
this.$sourceLinkCard = null;
this.$targetLinkCard = null;
+ this.$redLinkCard = null;
this.siteMapper = siteMapper;
}
@@ -104,8 +106,11 @@
this.$addLink = $( '<div>' )
.addClass( 'card__add-link' )
.text( mw.msg( 'cx-tools-link-add' ) );
+ this.$markLink = $( '<div>' )
+ .addClass( 'card__mark-link' )
+ .text( mw.msg( 'cx-tools-missing-link-mark-link' ) );
this.$targetLinkCard.find( '.card__link-info' )
- .append( this.$addLink, this.$removeLink );
+ .append( this.$addLink, this.$removeLink,
this.$markLink );
return this.$targetLinkCard.hide();
};
@@ -290,20 +295,32 @@
* @return {boolean}
*/
function isValidSelection( selection ) {
- var $parent, $parentSection;
+ var $parent;
- if ( !selection || !selection.toString().length ) {
+ if ( !selection ) {
return false;
}
$parent = getSelectionParent();
- if ( $parent.is( '[contenteditable="false"]' ) ) {
+ if ( $parent.is( '[contenteditable="false"]' ) ||
+ $parent.parents( '[contenteditable="false"]' ).length > 0
+ ) {
return false;
}
- // Get parent section
- $parentSection = $parent.parents( '[contenteditable]' );
- // Check if that section is editable
- return $parentSection.prop( 'contenteditable' );
+
+ if ( $parent.is( '.cx-target-link' ) ||
+ $parent.parents( '.cx-target-link' ).length > 0
+ ) {
+ return false;
+ }
+
+ if ( $parent.is( '.cx-redlink-marker' ) ||
+ $parent.parents( '.cx-redlink-marker' ).length > 0
+ ) {
+ return false;
+ }
+
+ return true;
}
/**
@@ -323,7 +340,8 @@
.text( linkText )
.attr( {
href: title,
- rel: 'mw:WikiLink'
+ rel: 'mw:WikiLink',
+ title: title
} );
if ( id ) {
@@ -340,18 +358,55 @@
};
/**
- * Make the given element to be an external link to a page in given
language.
- * @param {jQuery} $link Link element
+ * Create an external link to a page in given language.
* @param {string} target The page title in the target wikis
* @param {string} language Language code of target wikis
+ * @return {jQuery}
*/
- LinkCard.prototype.createExternalLink = function ( $link, target,
language ) {
+ LinkCard.prototype.createExternalLink = function ( target, language ) {
// Normalize the text for display and href
- var title = mw.Title.newFromText( target );
+ var $link,
+ title = mw.Title.newFromText( target );
+
+ $link = $( '<a>' )
+ .addClass( 'card__link-text' );
title = title ? title.getPrefixedText() : target;
this.setLinkAttributes( $link, title, language );
+
+ return $link;
+ };
+
+ /**
+ * Create a link to a new translation view for the source and target
titles.
+ * @param {string} sourceTitle The title of the article to be translated
+ * @param {string} targetTitle The title for the translated article
+ * @return {jQuery}
+ */
+ LinkCard.prototype.createTranslationLink = function ( sourceTitle ) {
+ var $link, language, uri;
+
+ language = mw.config.get( 'wgContentLanguage' );
+
+ uri = new mw.Uri().extend( {
+ from: mw.cx.sourceLanguage,
+ to: mw.cx.targetLanguage,
+ page: sourceTitle,
+ targetttitle: sourceTitle
+ } );
+
+ $link = $( '<a>' )
+ .attr( {
+ href: uri.toString(),
+ target: '_blank',
+ lang: language,
+ dir: $.uls.data.getDir( language ),
+ title: sourceTitle
+ } ).text( sourceTitle )
+ .addClass( 'cx-red-link' );
+
+ return $link;
};
/**
@@ -369,23 +424,19 @@
api = this.siteMapper.getApi( language );
getLink( api, title, language ).done( function ( response ) {
- var imgSrc, pageId, page;
+ var imgSrc, pageId, page, $externalLink;
pageId = Object.keys( response.query.pages )[ 0 ];
if ( pageId === '-1' ) {
- if ( linkCard.$link ) {
- linkCard.$link.addClass( 'new' );
- }
-
return;
}
page = response.query.pages[ pageId ];
- linkCard.createExternalLink(
- linkCard.$sourceLinkCard.find(
'.card__link-text' ),
- page.title,
- language
- );
+ $externalLink = linkCard.createExternalLink(
page.title, language );
+
+ linkCard.$sourceLinkCard.find( '.card__link-container' )
+ .empty()
+ .append( $externalLink );
if ( page.thumbnail ) {
imgSrc = page.thumbnail.source;
@@ -404,7 +455,7 @@
* @param {string} title The title
* @param {string} language Target language code
*/
- LinkCard.prototype.prepareTargetLinkCard = function ( title, language )
{
+ LinkCard.prototype.prepareTargetLinkCard = function ( title, language,
linkId ) {
var api,
linkCard = this;
@@ -412,64 +463,86 @@
return;
}
+ this.$addLink.hide();
+ this.$removeLink.hide();
+ this.$markLink.hide();
+
api = this.siteMapper.getApi( language );
getLink( api, title, language ).done( function ( response ) {
- var pageId, page, selection, imgSrc;
+ var pageId, page, selection, sourceTitle, imgSrc,
$externalLink,
+ $translationLink, $missingLinkMessage;
+ selection = mw.cx.selection.get();
pageId = Object.keys( response.query.pages )[ 0 ];
- if ( pageId === '-1' ) {
+
+ if ( pageId !== '-1' ) {
+ // Link was found.
+ page = response.query.pages[ pageId ];
+
+ // Set title
+ $( '.card__title' )
+ .text( mw.msg( 'cx-tools-link-title' )
);
+
+ // Create external link and add to card
+ $externalLink = linkCard.createExternalLink(
page.title, language );
+ linkCard.$targetLinkCard.find(
'.card__link-container' )
+ .empty()
+ .append( $externalLink );
+
+ if ( linkCard.isSourceLink() &&
isValidSelection( selection ) ) {
+ // Link is a source link and the
selection is valid
+ // Enable add link with link id.
+ linkCard.enableAddLink( selection,
page.title, linkId );
+ } else if ( linkCard.isEditableTargetLink() ) {
+ // Link is an editable target link.
Enable remove link.
+ linkCard.enableRemoveLink();
+ } else if ( isValidSelection( selection ) ) {
+ // Link came from text selection or
search
+ // Enable add link with no linkId
+ linkCard.enableAddLink( selection,
page.title );
+ }
+
+ // Add the page thumbnail if it exists.
+ if ( page.thumbnail ) {
+ imgSrc = page.thumbnail.source;
+ linkCard.$targetLinkCard.find(
'.card__link-image-container' )
+ .append( $( '<img>' ).attr(
'src', imgSrc ) );
+ }
+ } else if ( linkId ) {
+ // No link was found. This is a red link.
+
+ // Set title
+ linkCard.$targetLinkCard.find( '.card__title' )
+ .text( mw.msg(
'cx-tools-missing-link-title' ) );
+
+ if ( linkCard.isRedLink() ) {
+ // There is an existing redlink
+ sourceTitle = linkCard.getSourceLink(
linkId ).attr( 'title' );
+
+ // Create link to translate page in new
window and add to card
+ $translationLink =
linkCard.createTranslationLink( sourceTitle );
+ linkCard.$targetLinkCard.find(
'.card__link-container' )
+ .empty()
+ .append( $translationLink );
+
+ // Enable remove link for red links
+ linkCard.enableRemoveRedLink();
+ } else {
+ // Link is a red link marker
+ // Create missing link message and add
to card.
+ $missingLinkMessage = $( '<p>' )
+ .addClass(
'card__missing-link-message' )
+ .text( mw.msg(
'cx-tools-missing-link-text' ) );
+ linkCard.$targetLinkCard.find(
'.card__link-container' )
+ .empty()
+ .append( $missingLinkMessage );
+
+ // Enable mark link.
+ linkCard.enableMarkLink( title, linkId
);
+ }
+ } else {
linkCard.$targetLinkCard.hide();
return;
- }
- page = response.query.pages[ pageId ];
- selection = mw.cx.selection.get();
-
- linkCard.createExternalLink(
- linkCard.$targetLinkCard.find(
'.card__link-text' ),
- page.title,
- language
- );
-
- if ( isValidSelection( selection ) ) {
- // Some text selected in translation column and
it has a link.
- // Set up the add link button.
- linkCard.$addLink.click( function () {
- mw.cx.selection.restore( 'translation'
);
- linkCard.createInternalLink(
selection.toString(), page.title );
- } );
-
- // Show the add link button
- linkCard.$addLink.show();
-
- // Hide the remove link button
- linkCard.$removeLink.hide();
- } else {
- // Nothing selected. Hide the add link button.
- linkCard.$addLink.hide();
- linkCard.$removeLink.click( function () {
- mw.cx.selection.restore( 'translation'
);
- linkCard.removeLink();
- } );
- }
-
- if ( !linkCard.$link ) {
- // There is no link to remove. Card came from
search.
- // Prepare add link
- linkCard.$addLink.click( function () {
- mw.cx.selection.restore( 'translation'
);
- linkCard.createInternalLink(
selection.toString(), page.title );
- } );
-
- // Show the add link button
- linkCard.$addLink.show();
- // Hide the remove link button
- linkCard.$removeLink.hide();
- }
-
- if ( page.thumbnail ) {
- imgSrc = page.thumbnail.source;
- linkCard.$targetLinkCard.find(
'.card__link-image-container' )
- .append( $( '<img>' ).attr( 'src',
imgSrc ) );
}
linkCard.$targetLinkCard.show();
@@ -483,27 +556,19 @@
};
/**
- * For the link, get the corresponding link in source section.
+ * For the id, get the corresponding link in source section.
* @return {jQuery}
*/
- LinkCard.prototype.getSourceLink = function () {
- if ( !this.$link ) {
- return null;
- }
-
- return $( '.cx-link[data-linkid="' + this.$link.data( 'linkid'
) + '"]' );
+ LinkCard.prototype.getSourceLink = function ( id ) {
+ return $( '.cx-link[data-linkid="' + id + '"]' );
};
/**
- * For the link, get the corresponding link in target section.
+ * For the id, get the corresponding link in target section.
* @return {jQuery}
*/
- LinkCard.prototype.getTargetLink = function () {
- if ( !this.$link ) {
- return null;
- }
-
- return $( '.cx-target-link[data-linkid="' + this.$link.data(
'linkid' ) + '"]' );
+ LinkCard.prototype.getTargetLink = function ( id ) {
+ return $( '.cx-target-link[data-linkid="' + id + '"]' );
};
/**
@@ -550,6 +615,111 @@
};
/**
+ * Check if the link, the click of which caused the current link card
+ * is a red link.
+ * @return {boolean}
+ */
+ LinkCard.prototype.isRedLink = function () {
+ if ( !this.$link ) {
+ return false;
+ }
+
+ return this.$link.is( '.cx-red-link' );
+ };
+
+ /**
+ * Enables the add link control for adapted links
+ * @param {selection} selection The captured selection
+ * @param {string} title The title to be used for the new link
+ * @param {string} linkId The link id to be added to the new link
+ */
+ LinkCard.prototype.enableAddLink = function ( selection, title, linkId
) {
+ var linkCard = this;
+
+ this.$addLink.click( function () {
+ mw.cx.selection.restore( 'translation' );
+ if ( selection.toString().length > 0 ) {
+ linkCard.createInternalLink(
selection.toString(), title, linkId );
+ } else {
+ linkCard.createInternalLink( title, title,
linkId );
+ }
+ mw.cx.selection.restore( 'translation' );
+ } );
+
+ this.$addLink.show();
+ };
+
+ /**
+ * Enables the mark link control for missing links
+ * @param {string} title The title to be used for the new link
+ * @param {string} linkId The link id to be added to the new link
+ */
+ LinkCard.prototype.enableMarkLink = function ( title, linkId ) {
+ var $marker, $redLink;
+
+ $marker = $( '.cx-redlink-marker[data-linkid="' + linkId + '"]'
);
+
+ $redLink = $( '<a>' )
+ .prop( 'href', getValidTitle( title ) )
+ .html( $marker.html() )
+ .attr( {
+ 'rel': 'mw:WikiLink',
+ 'data-linkid': linkId,
+ 'title': title
+ } )
+ .addClass( 'cx-target-link cx-red-link' );
+
+ this.$markLink.click( function () {
+ mw.cx.selection.restore( 'translation' );
+ $marker.before( $redLink ).remove();
+ mw.cx.selection.restore( 'translation' );
+ } );
+
+ this.$markLink.show();
+ };
+
+ /**
+ * Enables the remove link control for adapted links
+ * @param {selection} selection The captured selection
+ * @param {string} title The title to be used for the new link
+ * @param {string} linkId The link id to be added to the new link
+ */
+ LinkCard.prototype.enableRemoveLink = function () {
+ var linkCard = this;
+
+ this.$removeLink.click( function () {
+ mw.cx.selection.restore( 'translation' );
+ linkCard.removeLink();
+ mw.cx.selection.restore( 'translation' );
+ } );
+
+ this.$removeLink.show();
+ };
+
+ /**
+ * Enables the remove link control for red links
+ */
+ LinkCard.prototype.enableRemoveRedLink = function () {
+ var $marker,
+ linkCard = this;
+
+ $marker = $( '<span>' )
+ .addClass( 'cx-redlink-marker
cx-redlink-marker-highlight' )
+ .attr( 'data-linkid', this.$link.attr( 'data-linkid' ) )
+ .html( this.$link.html() )
+ .click( markerClickHandler );
+
+ // Set up the remove link button
+ this.$removeLink.click( function () {
+ mw.cx.selection.restore( 'translation' );
+ linkCard.$link.before( $marker ).remove();
+ mw.cx.selection.restore( 'translation' );
+ } );
+
+ this.$removeLink.show();
+ };
+
+ /**
* Get a valid normalized title from the given text
* If the text is not suitable for the title, return null;
* Validation is done by mw.Title
@@ -572,7 +742,9 @@
* @param {string} [language] The language where the link points to.
*/
LinkCard.prototype.start = function ( link, language ) {
- var selection, title, targetTitle, sourceTitle, $targetLink,
$sourceLink;
+ var selection, title, linkId, targetTitle, sourceTitle,
+ $targetLink, $sourceLink,
+ linkCard = this;
// If language is not given, use target language
language = language || mw.cx.targetLanguage;
@@ -580,50 +752,117 @@
// Capture the current selection
selection = mw.cx.selection.get();
- // If the link is a source link, restore the selection
+ // If the click was on a source link, restore the selection
// in the translation column
if ( language === mw.cx.sourceLanguage ) {
mw.cx.selection.restore( 'translation' );
}
- // link can be link text or jQuery link object
+ // The link can be a string, a jQuery link or a jQuery span.
if ( typeof link === 'string' ) {
+ // link came from selection of search; just set title
title = getValidTitle( link );
- } else {
+ } else if ( link.is( '.cx-link' ) || link.is( '.cx-target-link'
) ) {
+ // An existing source or target link was clicked.
+ // Set the title and get the linkId. Store the link.
title = cleanupLinkHref( link.attr( 'href' ) );
this.$link = link;
+ linkId = link.attr( 'data-linkid' );
+ } else if ( link.is( '.cx-redlink-marker' ) ) {
+ // The click was on a red link marker span.
+ // Set the title and linkId
+ title = link.text();
+ linkId = link.attr( 'data-linkid' );
}
- // Do we have a valid title now?
+ // If we don't have a valid title, exit.
if ( !title ) {
this.stop();
return;
}
+ // UI highlighting
this.highlightLink();
- if ( this.$link && language === mw.cx.targetLanguage ) {
+
+ // If the click was on a target link, use the title
+ // as the target title. Otherwise, use the title as
+ // the source title.
+ if ( language === mw.cx.targetLanguage ) {
targetTitle = title;
} else {
sourceTitle = title;
}
- if ( !targetTitle ) {
- $targetLink = this.getTargetLink();
- targetTitle = $targetLink && $targetLink.attr( 'href' )
|| title;
- }
-
+ // If the click was on a target link or red link marker,
+ // we have no source title. Get the source link and create
+ // a source title from its href attribute
if ( !sourceTitle ) {
- $sourceLink = this.getSourceLink();
+ $sourceLink = this.getSourceLink( linkId );
sourceTitle = $sourceLink.attr( 'href' );
sourceTitle = cleanupLinkHref( sourceTitle );
}
- this.prepareSourceLinkCard( sourceTitle, mw.cx.sourceLanguage );
- this.prepareTargetLinkCard( targetTitle, mw.cx.targetLanguage );
+ // If the click was on a source link and valid text is selected
+ // create a new internal target link by adapting the source
title.
+ // Don't bother setting up the link cards
+ if ( this.isSourceLink() &&
+ isValidSelection( selection ) &&
+ selection.toString().length > 0
+ ) {
+ this.adapt( sourceTitle, mw.cx.targetLanguage )
+ .done( function ( adaptations ) {
+ if ( adaptations[ sourceTitle ] ) {
+ $targetLink =
linkCard.createInternalLink(
+ selection.toString(),
+ adaptations[
sourceTitle ],
+ linkId
+ );
+ }
+ } );
+ return;
+ }
- // If text is selected, create a new internal link
- if ( isValidSelection( selection ) && this.$link ) {
- $targetLink = this.createInternalLink(
selection.toString(), targetTitle, this.$link.data( 'linkid' ) );
+ // If no target text is selected, set up the source link card
+ this.prepareSourceLinkCard( sourceTitle, mw.cx.sourceLanguage );
+
+ // If the click was on a source link, we have no target title.
+ if ( !targetTitle ) {
+ // Check to see if there is an existing target link.
+ $targetLink = this.getTargetLink( linkId );
+
+ // If there is an existing target link, create a target
title
+ // from the href and set up the target link card.
+ if ( $targetLink && $targetLink.is( '.cx-target-link' )
) {
+ targetTitle = $targetLink.attr( 'href' );
+ this.prepareTargetLinkCard(
+ targetTitle,
+ mw.cx.targetLanguage,
+ linkId
+ );
+ } else {
+ // If there is not existing target link, adapt
the source title
+ // and then set up the target link card.
+ this.adapt( sourceTitle, mw.cx.targetLanguage )
+ .done( function ( adaptations ) {
+ if ( adaptations[ sourceTitle ]
) {
+ targetTitle =
adaptations[ sourceTitle ];
+
linkCard.prepareTargetLinkCard(
+ targetTitle,
+
mw.cx.targetLanguage,
+ linkId
+ );
+ }
+
+ } );
+ }
+ } else {
+ // If the click was on a target link or the target
title came
+ // from text selection or search, set up target card.
+ this.prepareTargetLinkCard(
+ targetTitle,
+ mw.cx.targetLanguage,
+ linkId
+ );
}
};
@@ -650,9 +889,9 @@
this.$link.addClass( 'cx-highlight--blue' );
if ( this.isSourceLink() ) {
- $connectedLink = this.getTargetLink();
+ $connectedLink = this.getTargetLink(
this.$link.attr( 'data-linkid' ) );
} else {
- $connectedLink = this.getSourceLink();
+ $connectedLink = this.getSourceLink(
this.$link.attr( 'data-linkid' ) );
}
// Both methods above can return null, so we need to
check if we have a link
@@ -717,6 +956,34 @@
return false;
}
+ /**
+ * Click handler for the red link markers in translation column.
+ */
+ function markerClickHandler() {
+ /*jshint validthis:true */
+ var $marker = $( this );
+
+ mw.hook( 'mw.cx.select.link' ).fire( $marker );
+
+ return false;
+ }
+
+ function highlightRedLinks() {
+ /*jshint validthis:true */
+ var $section = $( this );
+
+ $section.find( '.cx-redlink-marker' )
+ .addClass( 'cx-redlink-marker-highlight' );
+ }
+
+ function removeRedLinkHighlights() {
+ /*jshint validthis:true */
+ var $section = $( this );
+
+ $section.find( '.cx-redlink-marker' )
+ .removeClass( 'cx-redlink-marker-highlight' );
+ }
+
function adaptLinks( $section ) {
// WHYYYYYYY?
// @todo refactor to avoid global reference
@@ -726,6 +993,10 @@
// Handle clicks on the section, including future links
$section.on( 'click', 'a', linkClickHandler );
+
+ // Set up handlers for redlink highlights
+ $section.on( 'focus', highlightRedLinks );
+ $section.on( 'blur', removeRedLinkHighlights );
if ( $section.data( 'cx-draft' ) === true ) {
// This section is restored from draft. No need of link
adaptation.
@@ -744,7 +1015,8 @@
// updates the href appropriate for target language or removes
the link.
function apply( adaptations ) {
$links.map( function () {
- var $link = $( this ),
+ var $marker,
+ $link = $( this ),
href = $link.attr( 'href' );
// Identify this link as an adapted link in
translation
@@ -752,10 +1024,17 @@
href = cleanupLinkHref( href );
if ( adaptations[ href ] ) {
- $link.prop( 'href', adaptations[ href ]
);
+ $link
+ .prop( 'href', adaptations[
href ] )
+ .attr( 'title', adaptations[
href ] );
} else {
- // Remove the link
- $link.after( $( this ).text()
).remove();
+ $marker = $( '<span>' )
+ .addClass( 'cx-redlink-marker
cx-redlink-marker-highlight' )
+ .attr( 'data-linkid',
$link.attr( 'data-linkid' ) )
+ .html( $link.html() )
+ .click( markerClickHandler );
+
+ $link.replaceWith( $marker );
}
} );
}
diff --git a/modules/tools/styles/ext.cx.tools.link.less
b/modules/tools/styles/ext.cx.tools.link.less
index d9fceae..cc8f037 100644
--- a/modules/tools/styles/ext.cx.tools.link.less
+++ b/modules/tools/styles/ext.cx.tools.link.less
@@ -56,7 +56,7 @@
border-top: 1px solid #dddddd;
}
-.card__add-link {
+.card__add-link, .card__mark-link {
@vertical-margin: 10px;
@horizontal-margin: 15px;
.mw-ui-item;
@@ -118,6 +118,12 @@
white-space: nowrap;
}
}
+
+ .card__missing-link-message {
+ margin: 0;
+ padding: 0;
+ font-size: 1em;
+ }
}
.card__link-instruction {
@@ -134,3 +140,14 @@
color: #aaaaaa;
}
}
+
+.cx-redlink-marker-highlight {
+ color: #ccc;
+ border-bottom: 1px dashed #ccc;
+ cursor:pointer;
+}
+
+.cx-red-link {
+ color: red;
+}
+
--
To view, visit https://gerrit.wikimedia.org/r/181374
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6bce4bdd4688a5fb20c3268561329b126e57c3c7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Jsahleen <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits