mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-24 10:48:42 +00:00
Support only surfacing part of the document
Bug: T76541 Depends-On: I227a0d704b9b337cff2102d424be9795d6362ed7 Change-Id: Iac71a51c8696434658f24fbb41c8142237bd810e
This commit is contained in:
parent
bc02c44d36
commit
3269d53632
|
@ -52,6 +52,7 @@
|
|||
"VisualEditorEnableWikitextBetaFeature": false,
|
||||
"VisualEditorEnableDiffPage": false,
|
||||
"VisualEditorEnableDiffPageBetaFeature": false,
|
||||
"VisualEditorEnableVisualSectionEditing": false,
|
||||
"VisualEditorUseSingleEditTab": false,
|
||||
"VisualEditorSingleEditTabSwitchTime": 20160101000000,
|
||||
"VisualEditorTabPosition": "before",
|
||||
|
|
|
@ -899,6 +899,7 @@ class VisualEditorHooks {
|
|||
'tabPosition' => $veConfig->get( 'VisualEditorTabPosition' ),
|
||||
'tabMessages' => $veConfig->get( 'VisualEditorTabMessages' ),
|
||||
'singleEditTab' => $veConfig->get( 'VisualEditorUseSingleEditTab' ),
|
||||
'enableVisualSectionEditing' => $veConfig->get( 'VisualEditorEnableVisualSectionEditing' ),
|
||||
'showBetaWelcome' => $veConfig->get( 'VisualEditorShowBetaWelcome' ),
|
||||
'enableTocWidget' => $veConfig->get( 'VisualEditorEnableTocWidget' ),
|
||||
'enableWikitext' => (
|
||||
|
|
|
@ -29,7 +29,7 @@ OO.inheritClass( ve.dm.MWHeadingNode, ve.dm.HeadingNode );
|
|||
ve.dm.MWHeadingNode.static.name = 'mwHeading';
|
||||
|
||||
// Headings in wikitext only work in some contexts, they're impossible e.g. in list items
|
||||
ve.dm.MWHeadingNode.static.suggestedParentNodeTypes = [ 'document', 'tableCell', 'div' ];
|
||||
ve.dm.MWHeadingNode.static.suggestedParentNodeTypes = [ 'document', 'tableCell', 'div', 'section' ];
|
||||
|
||||
/* Registration */
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ OO.inheritClass( ve.dm.MWPreformattedNode, ve.dm.PreformattedNode );
|
|||
ve.dm.MWPreformattedNode.static.name = 'mwPreformatted';
|
||||
|
||||
// Indent-pre in wikitext only works in some contexts, it's impossible e.g. in list items
|
||||
ve.dm.MWPreformattedNode.static.suggestedParentNodeTypes = [ 'document', 'tableCell' ];
|
||||
ve.dm.MWPreformattedNode.static.suggestedParentNodeTypes = [ 'document', 'tableCell', 'div', 'section' ];
|
||||
|
||||
/* Registration */
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ ve.dm.MWTableNode.static.classAttributes = {
|
|||
|
||||
// Tables in wikitext only work in some contexts, they're impossible e.g. in list items
|
||||
ve.dm.MWTableNode.static.suggestedParentNodeTypes = [
|
||||
'document', 'div', 'tableCell', 'tableCaption', 'mwImageCaption',
|
||||
'document', 'div', 'tableCell', 'tableCaption', 'mwImageCaption', 'section',
|
||||
// TODO: `paragraph` isn't really a suggested table parent. However,
|
||||
// allowing it here interacts with our post-insertion cleanup for block
|
||||
// nodes so that empty paragraphs get properly removed. We should find a
|
||||
|
|
|
@ -50,3 +50,13 @@
|
|||
color: #999;
|
||||
float: none;
|
||||
}
|
||||
|
||||
/* Reset section node styles */
|
||||
.ve-init-mw-target .ve-ce-sectionNode:before,
|
||||
.ve-init-mw-target .ve-ce-sectionNode:after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
.ve-init-mw-target .ve-ce-surface-enabled .ve-ce-sectionNode:not( .ve-ce-activeNode-active ) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
@ -182,8 +182,8 @@
|
|||
function parseSection( section ) {
|
||||
var parsedSection = section;
|
||||
// Section must be a number, 'new' or 'T-' prefixed
|
||||
if ( section !== 'new' && section.indexOf( 'T-' ) !== 0 ) {
|
||||
parsedSection = +section;
|
||||
if ( section !== 'new' ) {
|
||||
parsedSection = section.indexOf( 'T-' ) === 0 ? +section.slice( 2 ) : +section;
|
||||
if ( isNaN( parsedSection ) ) {
|
||||
parsedSection = null;
|
||||
}
|
||||
|
@ -951,19 +951,11 @@
|
|||
history.pushState( { tag: 'visualeditor' }, document.title, this.href );
|
||||
}
|
||||
|
||||
if ( mode === 'visual' ) {
|
||||
// Get section based on heading count (may differ from wikitext section count)
|
||||
targetPromise = getTarget( mode ).then( function ( target ) {
|
||||
target.saveEditSection( $( e.target ).closest( 'h1, h2, h3, h4, h5, h6' ).get( 0 ) );
|
||||
return target;
|
||||
} );
|
||||
} else {
|
||||
// Use section from URL
|
||||
if ( section === undefined ) {
|
||||
section = parseSection( uri.query.section );
|
||||
}
|
||||
targetPromise = getTarget( mode, section );
|
||||
// Use section from URL
|
||||
if ( section === undefined ) {
|
||||
section = parseSection( uri.query.section );
|
||||
}
|
||||
targetPromise = getTarget( mode, section );
|
||||
activateTarget( mode, section, targetPromise );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1138,7 +1138,7 @@ ve.init.mw.DesktopArticleTarget.prototype.getSaveDialogOpeningData = function ()
|
|||
* Remember the window's scroll position.
|
||||
*/
|
||||
ve.init.mw.DesktopArticleTarget.prototype.saveScrollPosition = function () {
|
||||
if ( this.getDefaultMode() === 'source' && this.section !== null ) {
|
||||
if ( ( this.getDefaultMode() === 'source' || this.enableVisualSectionEditing ) && this.section !== null ) {
|
||||
// Reset scroll to top if doing real section editing
|
||||
this.scrollTop = 0;
|
||||
} else {
|
||||
|
@ -1306,7 +1306,7 @@ ve.init.mw.DesktopArticleTarget.prototype.updateHistoryState = function () {
|
|||
* Page modifications for switching back to view mode.
|
||||
*/
|
||||
ve.init.mw.DesktopArticleTarget.prototype.restorePage = function () {
|
||||
var uri, keys, section, $section;
|
||||
var uri, keys, fragment, target;
|
||||
|
||||
// Skins like monobook don't have a tab for view mode and instead just have the namespace tab
|
||||
// selected. We didn't deselect the namespace tab, so we're ready after deselecting #ca-ve-edit.
|
||||
|
@ -1330,30 +1330,22 @@ ve.init.mw.DesktopArticleTarget.prototype.restorePage = function () {
|
|||
if ( 'veaction' in uri.query ) {
|
||||
delete uri.query.veaction;
|
||||
}
|
||||
if ( 'section' in uri.query ) {
|
||||
if ( this.section !== null ) {
|
||||
// Translate into a fragment for the new URI:
|
||||
// This should be after replacePageContent if this is post-save, so we can just look
|
||||
// at the headers on the page.
|
||||
section = uri.query.section.toString().indexOf( 'T-' ) === 0 ? +uri.query.section.slice( 2 ) : uri.query.section;
|
||||
$section = this.$editableContent.find( 'h1, h2, h3, h4, h5, h6' )
|
||||
// Ignore headings inside TOC
|
||||
.filter( function () {
|
||||
return $( this ).closest( '#toc' ).length === 0;
|
||||
} );
|
||||
if ( section === 'new' ) {
|
||||
// A new section is appended to the end, so take the last one.
|
||||
section = $section.length;
|
||||
}
|
||||
$section = $section.eq( section - 1 ).find( '.mw-headline' );
|
||||
fragment = this.getSectionFragmentFromPage();
|
||||
if ( fragment ) {
|
||||
uri.fragment = fragment;
|
||||
this.viewUri.fragment = fragment;
|
||||
target = document.getElementById( fragment );
|
||||
|
||||
if ( $section.length && $section.attr( 'id' ) ) {
|
||||
uri.fragment = $section.attr( 'id' );
|
||||
this.viewUri.fragment = uri.fragment;
|
||||
|
||||
// Scroll the page to the edited section
|
||||
setTimeout( function () {
|
||||
$section[ 0 ].scrollIntoView( true );
|
||||
} );
|
||||
if ( target ) {
|
||||
// Scroll the page to the edited section
|
||||
setTimeout( function () {
|
||||
target.scrollIntoView( true );
|
||||
} );
|
||||
}
|
||||
}
|
||||
delete uri.query.section;
|
||||
}
|
||||
|
@ -1463,34 +1455,6 @@ ve.init.mw.DesktopArticleTarget.prototype.replacePageContent = function (
|
|||
mw.libs.ve.setupEditLinks();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the numeric index of a section in the page.
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} heading Heading element of section
|
||||
*/
|
||||
ve.init.mw.DesktopArticleTarget.prototype.getEditSection = function ( heading ) {
|
||||
var $page = $( '#mw-content-text' ),
|
||||
section = 0;
|
||||
$page.find( 'h1, h2, h3, h4, h5, h6' ).not( '#toc h2' ).each( function () {
|
||||
section++;
|
||||
if ( this === heading ) {
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
return section;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store the section for which the edit link has been triggered.
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} heading Heading element of section
|
||||
*/
|
||||
ve.init.mw.DesktopArticleTarget.prototype.saveEditSection = function ( heading ) {
|
||||
this.section = this.getEditSection( heading );
|
||||
};
|
||||
|
||||
/**
|
||||
* Add onunload and onbeforeunload handlers.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* @param {Object} [config] Configuration options
|
||||
*/
|
||||
ve.init.mw.ArticleTarget = function VeInitMwArticleTarget( config ) {
|
||||
var enableVisualSectionEditing;
|
||||
|
||||
config = config || {};
|
||||
config.toolbarConfig = $.extend( {
|
||||
shadow: true,
|
||||
|
@ -38,6 +40,8 @@ ve.init.mw.ArticleTarget = function VeInitMwArticleTarget( config ) {
|
|||
this.originalHtml = null;
|
||||
this.toolbarSaveButton = null;
|
||||
this.pageExists = mw.config.get( 'wgRelevantArticleId', 0 ) !== 0;
|
||||
enableVisualSectionEditing = mw.config.get( 'wgVisualEditorConfig' ).enableVisualSectionEditing;
|
||||
this.enableVisualSectionEditing = enableVisualSectionEditing === true || enableVisualSectionEditing === this.constructor.static.trackingName;
|
||||
this.toolbarScrollOffset = mw.config.get( 'wgVisualEditorToolbarScrollOffset', 0 );
|
||||
// A workaround, as default URI does not get updated after pushState (T74334)
|
||||
this.currentUri = new mw.Uri( location.href );
|
||||
|
@ -224,7 +228,7 @@ ve.init.mw.ArticleTarget.static.documentCommands = ve.init.mw.ArticleTarget.supe
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ve.init.mw.ArticleTarget.static.parseDocument = function ( documentString, mode, section ) {
|
||||
ve.init.mw.ArticleTarget.static.parseDocument = function ( documentString, mode, section, onlySection ) {
|
||||
// Add trailing linebreak to non-empty wikitext documents for consistency
|
||||
// with old editor and usability. Will be stripped on save. T156609
|
||||
if ( mode === 'source' && documentString ) {
|
||||
|
@ -232,7 +236,7 @@ ve.init.mw.ArticleTarget.static.parseDocument = function ( documentString, mode,
|
|||
}
|
||||
|
||||
// Parent method
|
||||
return ve.init.mw.ArticleTarget.super.static.parseDocument.call( this, documentString, mode, section );
|
||||
return ve.init.mw.ArticleTarget.super.static.parseDocument.call( this, documentString, mode, section, onlySection );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -340,7 +344,8 @@ ve.init.mw.ArticleTarget.prototype.updateTabs = function ( editing ) {
|
|||
* @param {string} status Text status message
|
||||
*/
|
||||
ve.init.mw.ArticleTarget.prototype.loadSuccess = function ( response ) {
|
||||
var data = response ? ( response.visualeditor || response.visualeditoredit ) : null;
|
||||
var mode, section,
|
||||
data = response ? ( response.visualeditor || response.visualeditoredit ) : null;
|
||||
|
||||
if ( !data || typeof data.content !== 'string' ) {
|
||||
this.loadFail( 've-api', 'No HTML content in response from server' );
|
||||
|
@ -350,7 +355,9 @@ ve.init.mw.ArticleTarget.prototype.loadSuccess = function ( response ) {
|
|||
this.etag = data.etag;
|
||||
this.fromEditedState = !!data.fromEditedState;
|
||||
this.switched = data.switched || 'wteswitched' in new mw.Uri( location.href ).query;
|
||||
this.doc = this.constructor.static.parseDocument( this.originalHtml, this.getDefaultMode() );
|
||||
mode = this.getDefaultMode();
|
||||
section = ( mode === 'source' || this.enableVisualSectionEditing ) ? this.section : null;
|
||||
this.doc = this.constructor.static.parseDocument( this.originalHtml, mode, section );
|
||||
|
||||
// Properties that don't come from the API
|
||||
this.initialSourceRange = data.initialSourceRange;
|
||||
|
@ -600,8 +607,8 @@ ve.init.mw.ArticleTarget.prototype.storeDocState = function ( html ) {
|
|||
request: {
|
||||
pageName: this.getPageName(),
|
||||
mode: mode,
|
||||
// Only source mode fetches data by section
|
||||
section: mode === 'source' ? this.section : null
|
||||
// Check true section editing is in use
|
||||
section: ( mode === 'source' || this.enableVisualSectionEditing ) ? this.section : null
|
||||
},
|
||||
response: {
|
||||
etag: this.etag,
|
||||
|
@ -1024,7 +1031,6 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogPreview = function () {
|
|||
if ( ve.getProp( response, 'visualeditor', 'result' ) === 'success' ) {
|
||||
doc = target.constructor.static.parseDocument( response.visualeditor.content, 'visual' );
|
||||
target.saveDialog.showPreview( doc, baseDoc );
|
||||
|
||||
} else {
|
||||
target.saveDialog.showPreview(
|
||||
ve.msg(
|
||||
|
@ -2101,35 +2107,36 @@ ve.init.mw.ArticleTarget.prototype.getSaveDialogOpeningData = function () {
|
|||
* @method
|
||||
*/
|
||||
ve.init.mw.ArticleTarget.prototype.restoreEditSection = function () {
|
||||
var headingText,
|
||||
section,
|
||||
var dmDoc, headingModel, headingView, headingText,
|
||||
section = this.section,
|
||||
surface = this.getSurface(),
|
||||
mode = surface.getMode(),
|
||||
surfaceView, $documentNode, $section, headingNode;
|
||||
mode = surface.getMode();
|
||||
|
||||
if ( this.section !== null && this.section !== 'new' && this.section !== 0 && this.section !== 'T-0' ) {
|
||||
if ( section !== null && section !== 'new' && section !== 0 && section !== 'T-0' ) {
|
||||
if ( mode === 'visual' ) {
|
||||
// Get numerical part of section (strip 'T-'' if present)
|
||||
section = this.section.toString().indexOf( 'T-' ) === 0 ? +this.section.slice( 2 ) : this.section;
|
||||
surfaceView = surface.getView();
|
||||
$documentNode = surfaceView.getDocument().getDocumentNode().$element;
|
||||
// Find all headings including those inside templates, not just HeadingNodes
|
||||
$section = $documentNode.find( 'h1, h2, h3, h4, h5, h6' )
|
||||
// Ignore headings inside TOC
|
||||
.filter( function () {
|
||||
return $( this ).closest( '.ve-ui-mwTocWidget' ).length === 0;
|
||||
} )
|
||||
.eq( section - 1 );
|
||||
headingNode = $section.data( 'view' );
|
||||
|
||||
if ( $section.length && new mw.Uri().query.summary === undefined ) {
|
||||
// Due to interactions with Translate, strip out mw-
|
||||
// editsection from the heading.
|
||||
headingText = $section.clone().find( 'span.mw-editsection' ).remove().end().text();
|
||||
}
|
||||
|
||||
if ( headingNode ) {
|
||||
this.goToHeading( headingNode );
|
||||
dmDoc = surface.getModel().getDocument();
|
||||
// In ve.unwrapParsoidSections we copy the data-mw-section-id from the section element
|
||||
// to the heading. Iterate over headings to find the one with the correct attribute
|
||||
// in originalDomElements.
|
||||
dmDoc.getNodesByType( 'mwHeading' ).some( function ( heading ) {
|
||||
var domElements = heading.getOriginalDomElements( dmDoc.getStore() );
|
||||
if (
|
||||
domElements && domElements[ 0 ].nodeType === Node.ELEMENT_NODE &&
|
||||
+domElements[ 0 ].getAttribute( 'data-mw-section-id' ) === section
|
||||
) {
|
||||
headingModel = heading;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
if ( headingModel ) {
|
||||
headingView = surface.getView().getDocument().getDocumentNode().getNodeFromOffset( headingModel.getRange().start );
|
||||
if ( new mw.Uri().query.summary === undefined ) {
|
||||
headingText = headingView.$element.text();
|
||||
}
|
||||
if ( !this.enableVisualSectionEditing ) {
|
||||
this.goToHeading( headingView );
|
||||
}
|
||||
}
|
||||
} else if ( mode === 'source' ) {
|
||||
// With elements of extractSectionTitle + stripSectionName TODO:
|
||||
|
@ -2216,6 +2223,36 @@ ve.init.mw.ArticleTarget.prototype.scrollToHeading = function ( headingNode ) {
|
|||
$window.scrollTop( headingNode.$element.offset().top - this.getToolbar().$element.height() );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the section ID's hash fragment using the page's PHP HTML
|
||||
*
|
||||
* TODO: Do this in a less skin-dependent way
|
||||
*
|
||||
* @param {number} section Section ID
|
||||
* @return {string} Hash fragment, or null if not found
|
||||
*/
|
||||
ve.init.mw.ArticleTarget.prototype.getSectionFragmentFromPage = function () {
|
||||
var section, $sections, $section;
|
||||
|
||||
// Assume there are section edit links, as the user just did a section edit. This also means
|
||||
// that the section numbers line up correctly, as not every H_ tag is a numbered section.
|
||||
$sections = $( '.mw-editsection' );
|
||||
if ( this.section === 'new' ) {
|
||||
// A new section is appended to the end, so take the last one.
|
||||
section = $sections.length;
|
||||
} else {
|
||||
section = this.section;
|
||||
}
|
||||
if ( section > 0 ) {
|
||||
$section = $sections.eq( section - 1 ).parent().find( '.mw-headline' );
|
||||
|
||||
if ( $section.length && $section.attr( 'id' ) ) {
|
||||
return $section.attr( 'id' ) || '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the beta dialog as needed
|
||||
*/
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
* @param {string} pageName Page name to request
|
||||
* @param {Object} [options] Options
|
||||
* @param {boolean} [options.sessionStore] Store result in session storage (by page+mode+section) for auto-save
|
||||
* @param {number|string} [options.section] Section to edit, number or 'new' (currently just source mode)
|
||||
* @param {number|null|string} [options.section] Section to edit; number, null or 'new' (currently just source mode)
|
||||
* @param {number} [options.oldId] Old revision ID. Current if omitted.
|
||||
* @param {string} [options.targetName] Optional target name for tracking
|
||||
* @param {boolean} [options.modified] The page was been modified before loading (e.g. in source mode)
|
||||
|
@ -118,7 +118,7 @@
|
|||
* @return {jQuery.Promise} Abortable promise resolved with a JSON object
|
||||
*/
|
||||
requestPageData: function ( mode, pageName, options ) {
|
||||
var sessionState, request, dataPromise, apiRequest;
|
||||
var sessionState, request, section, dataPromise, apiRequest, enableVisualSectionEditing;
|
||||
|
||||
options = options || {};
|
||||
apiRequest = mode === 'source' ?
|
||||
|
@ -133,12 +133,15 @@
|
|||
|
||||
if ( sessionState ) {
|
||||
request = sessionState.request || {};
|
||||
// Check true section editing is in use
|
||||
enableVisualSectionEditing = mw.config.get( 'wgVisualEditorConfig' ).enableVisualSectionEditing;
|
||||
section = request.mode === 'source' || enableVisualSectionEditing === true || enableVisualSectionEditing === options.targetName ?
|
||||
options.section : null;
|
||||
// Check the requested page, mode and section match the stored one
|
||||
if (
|
||||
request.pageName === pageName &&
|
||||
request.mode === mode &&
|
||||
// Only check sections in source mode
|
||||
( request.mode !== 'source' || request.section === options.section )
|
||||
request.section === section
|
||||
// NB we don't cache by oldid so that cached results can be recovered
|
||||
// even if the page has been since edited
|
||||
) {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
metadataIdRegExp = ve.init.platform.getMetadataIdRegExp(),
|
||||
data = response ? ( response.visualeditor || response.visualeditoredit ) : null;
|
||||
if ( data && typeof data.content === 'string' ) {
|
||||
doc = targetClass.static.parseDocument( data.content, 'visual', section );
|
||||
doc = targetClass.static.parseDocument( data.content, 'visual', section, true );
|
||||
// Strip RESTBase IDs
|
||||
Array.prototype.forEach.call( doc.querySelectorAll( '[id^="mw"]' ), function ( element ) {
|
||||
if ( element.id.match( metadataIdRegExp ) ) {
|
||||
|
|
|
@ -178,9 +178,11 @@ ve.init.mw.Target.prototype.createModelFromDom = function () {
|
|||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @param {number} [section] Section
|
||||
* @param {number|string|null} section Section
|
||||
* @param {boolean} [onlySection] Only return the requested section, otherwise returns the
|
||||
* whole document with just the requested section still wrapped (visual mode only).
|
||||
*/
|
||||
ve.init.mw.Target.static.parseDocument = function ( documentString, mode, section ) {
|
||||
ve.init.mw.Target.static.parseDocument = function ( documentString, mode, section, onlySection ) {
|
||||
var doc, sectionNode;
|
||||
if ( mode === 'source' ) {
|
||||
// Parent method
|
||||
|
@ -189,14 +191,17 @@ ve.init.mw.Target.static.parseDocument = function ( documentString, mode, sectio
|
|||
// Parsoid documents are XHTML so we can use parseXhtml which fixed some IE issues.
|
||||
doc = ve.parseXhtml( documentString );
|
||||
if ( section !== undefined ) {
|
||||
sectionNode = doc.body.querySelector( '[data-mw-section-id="' + section + '"]' );
|
||||
doc.body.innerHTML = '';
|
||||
if ( sectionNode ) {
|
||||
doc.body.appendChild( sectionNode );
|
||||
if ( onlySection ) {
|
||||
sectionNode = doc.body.querySelector( '[data-mw-section-id="' + section + '"]' );
|
||||
doc.body.innerHTML = '';
|
||||
if ( sectionNode ) {
|
||||
doc.body.appendChild( sectionNode );
|
||||
}
|
||||
} else {
|
||||
// Strip Parsoid sections
|
||||
ve.unwrapParsoidSections( doc.body, section );
|
||||
}
|
||||
}
|
||||
// Strip Parsoid sections
|
||||
ve.unwrapParsoidSections( doc.body );
|
||||
// Strip legacy IDs, for example in section headings
|
||||
ve.stripParsoidFallbackIds( doc.body );
|
||||
// Fix relative or missing base URL if needed
|
||||
|
@ -275,6 +280,11 @@ ve.init.mw.Target.prototype.getHtml = function ( newDoc, oldDoc ) {
|
|||
'div.donut-container' // Web of Trust (T189148)
|
||||
].join( ',' ) )
|
||||
.remove();
|
||||
|
||||
// data-mw-section-id is copied to headings by ve.unwrapParsoidSections
|
||||
// Remove these to avoid triggering selser.
|
||||
$( newDoc ).find( '[data-mw-section-id]:not( section )' ).removeAttr( 'data-mw-section-id' );
|
||||
|
||||
// Add doctype manually
|
||||
return '<!doctype html>' + ve.serializeXhtml( newDoc );
|
||||
};
|
||||
|
|
|
@ -171,9 +171,9 @@ ve.ui.MWTocWidget.prototype.build = function () {
|
|||
return $list.children( 'li' ).length + ( n === stack.length - 1 ? 1 : 0 );
|
||||
}
|
||||
|
||||
function linkClickHandler( heading ) {
|
||||
function linkClickHandler( /* heading */ ) {
|
||||
surfaceView.focus();
|
||||
ve.init.target.goToHeading( heading );
|
||||
// TODO: Impement heading scroll
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,19 @@ ve.decodeURIComponentIntoArticleTitle = function ( s, preserveUnderscores ) {
|
|||
* Unwrap Parsoid sections
|
||||
*
|
||||
* @param {HTMLElement} element Parent element, e.g. document body
|
||||
* @param {number} [keepSection] Section to keep
|
||||
*/
|
||||
ve.unwrapParsoidSections = function ( element ) {
|
||||
ve.unwrapParsoidSections = function ( element, keepSection ) {
|
||||
Array.prototype.forEach.call( element.querySelectorAll( 'section[data-mw-section-id]' ), function ( section ) {
|
||||
var parent = section.parentNode;
|
||||
var parent = section.parentNode,
|
||||
sectionId = section.getAttribute( 'data-mw-section-id' );
|
||||
// Copy section ID to first child (should be a heading)
|
||||
if ( sectionId > 0 ) {
|
||||
section.firstChild.setAttribute( 'data-mw-section-id', sectionId );
|
||||
}
|
||||
if ( keepSection !== undefined && +sectionId === keepSection ) {
|
||||
return;
|
||||
}
|
||||
while ( section.firstChild ) {
|
||||
parent.insertBefore( section.firstChild, section );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue