Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | 1x 6x 1x 1x 1x 1x 4x 4x 4x 1x 2x 2x 1x 2x 2x 1x 5x 5x 5x 5x 5x 3x 5x 5x 5x 5x 5x 5x 5x 2x 2x 2x 3x 3x 3x 3x 3x 3x 5x 3x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 1x 1x 1x 1x | /*! * VisualEditor UserInterface ListAction class. * * @copyright See AUTHORS.txt */ /** * List action. * * @class * @extends ve.ui.Action * @constructor * @param {ve.ui.Surface} surface Surface to act on * @param {string} [source] */ ve.ui.ListAction = function VeUiListAction() { // Parent constructor ve.ui.ListAction.super.apply( this, arguments ); }; /* Inheritance */ OO.inheritClass( ve.ui.ListAction, ve.ui.Action ); /* Static Properties */ ve.ui.ListAction.static.name = 'list'; ve.ui.ListAction.static.methods = [ 'wrap', 'unwrap', 'toggle', 'wrapOnce' ]; /* Methods */ /** * Check if the current selection is wrapped in a list of a given style * * @param {string|null} style List style, e.g. 'number' or 'bullet', or null for any style * @param {string} [listType='list'] List type * @return {boolean} Current selection is all wrapped in a list */ ve.ui.ListAction.prototype.allWrapped = function ( style, listType ) { listType = listType || 'list'; var attributes = style ? { style: style } : undefined; return this.surface.getModel().getFragment().hasMatchingAncestor( listType, attributes, true ); }; /** * Toggle a list around content. * * @param {string} style List style, e.g. 'number' or 'bullet' * @param {boolean} noBreakpoints Don't create breakpoints * @param {string} [listType='list'] List type * @return {boolean} Action was executed */ ve.ui.ListAction.prototype.toggle = function ( style, noBreakpoints, listType ) { Iif ( this.allWrapped( style, listType ) ) { return this.unwrap( noBreakpoints, listType ); } else { return this.wrap( style, noBreakpoints, listType ); } }; /** * Add a list around content only if it has no list already. * * @param {string} style List style, e.g. 'number' or 'bullet' * @param {boolean} noBreakpoints Don't create breakpoints * @param {string} [listType='list'] List type * @return {boolean} Action was executed */ ve.ui.ListAction.prototype.wrapOnce = function ( style, noBreakpoints, listType ) { // Check for a list of any style Eif ( !this.allWrapped( null, listType ) ) { return this.wrap( style, noBreakpoints, listType ); } return false; }; /** * Add a list around content. * * TODO: Refactor functionality into {ve.dm.SurfaceFragment}. * * @param {string} style List style, e.g. 'number' or 'bullet' * @param {boolean} noBreakpoints Don't create breakpoints * @param {string} [listType='list'] List type * @return {boolean} Action was executed */ ve.ui.ListAction.prototype.wrap = function ( style, noBreakpoints, listType ) { var surfaceModel = this.surface.getModel(), selection = surfaceModel.getSelection(); Iif ( !( selection instanceof ve.dm.LinearSelection ) ) { return false; } listType = listType || 'list'; if ( !noBreakpoints ) { surfaceModel.breakpoint(); } var documentModel = surfaceModel.getDocument(); var range = selection.getRange(); // TODO: Would be good to refactor at some point and avoid/abstract path split for block slug // and not block slug. Iif ( range.isCollapsed() && !documentModel.data.isContentOffset( range.to ) && documentModel.hasSlugAtOffset( range.to ) ) { // Inside block level slug var fragment = surfaceModel.getFragment( null, true ) .insertContent( [ { type: 'paragraph' }, { type: '/paragraph' } ] ) .collapseToStart() .adjustLinearSelection( 1, 1 ) .select(); range = fragment.getSelection().getRange(); } var previousList; var groups = documentModel.getCoveredSiblingGroups( range ); for ( var i = 0; i < groups.length; i++ ) { var group = groups[ i ]; // TODO: Allow conversion between different list types if ( group.grandparent && group.grandparent.getType() === listType ) { Eif ( group.grandparent !== previousList ) { surfaceModel.getLinearFragment( group.grandparent.getOuterRange(), true ) // Change the list style .changeAttributes( { style: style } ); previousList = group.grandparent; } } else { // Get a range that covers the whole group var groupRange = new ve.Range( group.nodes[ 0 ].getOuterRange().start, group.nodes[ group.nodes.length - 1 ].getOuterRange().end ); var element = { type: listType }; Eif ( style ) { element.attributes = { style: style }; } var itemElement = ve.dm.modelRegistry.lookup( listType ).static.createItem(); surfaceModel.getLinearFragment( groupRange, true ) // Convert everything to paragraphs first .convertNodes( 'paragraph', null, { generated: 'wrapper' } ) // Wrap everything in a list and each content branch in a listItem .wrapAllNodes( element, itemElement ); } } if ( !noBreakpoints ) { surfaceModel.breakpoint(); } return true; }; /** * Remove list around content. * * TODO: Refactor functionality into {ve.dm.SurfaceFragment}. * * @param {boolean} noBreakpoints Don't create breakpoints * @param {string} [listType='list'] List type * @return {boolean} Action was executed */ ve.ui.ListAction.prototype.unwrap = function ( noBreakpoints, listType ) { var surfaceModel = this.surface.getModel(); Iif ( !( surfaceModel.getSelection() instanceof ve.dm.LinearSelection ) ) { return false; } Eif ( !noBreakpoints ) { surfaceModel.breakpoint(); } var indentationAction = ve.ui.actionFactory.create( 'indentation', this.surface ); var documentModel = surfaceModel.getDocument(); listType = listType || 'list'; var node; do { node = documentModel.getBranchNodeFromOffset( surfaceModel.getSelection().getRange().start ); } while ( node.hasMatchingAncestor( listType ) && indentationAction.decrease() ); Eif ( !noBreakpoints ) { surfaceModel.breakpoint(); } return true; }; /* Registration */ ve.ui.actionFactory.register( ve.ui.ListAction ); |