Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.DOMConverter.js |
— | — | @@ -35,7 +35,9 @@ |
36 | 36 | * and optionally 'attribs', WikiDom-specific attributes implied by the element name. |
37 | 37 | */ |
38 | 38 | DOMConverter.prototype._getHTMLtoWikiDomHandlerInfo = function ( nodeName ) { |
| 39 | + var wikiName = ''; |
39 | 40 | switch ( nodeName.toLowerCase() ) { |
| 41 | + // leaf nodes first, with fall-through to last leaf.. |
40 | 42 | case 'p': |
41 | 43 | return { |
42 | 44 | handler: this._convertHTMLLeaf, |
— | — | @@ -121,7 +123,7 @@ |
122 | 124 | type: 'blockquote' |
123 | 125 | }; |
124 | 126 | default: |
125 | | - console.log( 'HTML to Wiki DOM conversion error. Unsupported node name ' + |
| 127 | + console.log( 'HTML to Wiki DOM conversion warning: Unknown node name ' + |
126 | 128 | nodeName ); |
127 | 129 | return { |
128 | 130 | handler: this._convertHTMLBranch, |
— | — | @@ -139,8 +141,9 @@ |
140 | 142 | * @returns {String} WikiDom annotation type or undefined if element name does |
141 | 143 | * not map to an annotation. |
142 | 144 | */ |
143 | | -DOMConverter.prototype._getWikiDomAnnotationType = function ( nodeName, warn ) { |
144 | | - switch ( nodeName.toLowerCase() ) { |
| 145 | +DOMConverter.prototype._getWikiDomAnnotationType = function ( node, warn ) { |
| 146 | + var name = node.nodeName.toLowerCase(); |
| 147 | + switch ( name ) { |
145 | 148 | case 'i': |
146 | 149 | return 'textStyle/italic'; |
147 | 150 | case 'b': |
— | — | @@ -148,7 +151,13 @@ |
149 | 152 | case 'span': |
150 | 153 | return 'textStyle/span'; |
151 | 154 | case 'a': |
152 | | - return 'link/unknown'; // XXX: distinguish internal / external etc |
| 155 | + var atype = node.getAttribute( 'data-type' ); |
| 156 | + if ( atype ) { |
| 157 | + return 'link/' + atype; |
| 158 | + } else { |
| 159 | + return 'link/unknown'; |
| 160 | + } |
| 161 | + break; // make JSHint happy |
153 | 162 | case 'template': |
154 | 163 | return 'object/template'; |
155 | 164 | case 'ref': |
— | — | @@ -157,7 +166,7 @@ |
158 | 167 | return 'object/includeonly'; // XXX |
159 | 168 | default: |
160 | 169 | if ( warn ) { |
161 | | - console.log( 'HTML to Wiki DOM conversion error. Unsupported html annotation ' + |
| 170 | + console.log( 'HTML to Wiki DOM conversion warning: Unsupported html annotation ' + |
162 | 171 | nodeName ); |
163 | 172 | } |
164 | 173 | return undefined; |
— | — | @@ -201,7 +210,7 @@ |
202 | 211 | switch ( cnode.nodeType ) { |
203 | 212 | case Node.ELEMENT_NODE: |
204 | 213 | // Check if element type is an annotation |
205 | | - var annotationtype = this._getWikiDomAnnotationType( cnode.nodeName ); |
| 214 | + var annotationtype = this._getWikiDomAnnotationType( cnode ); |
206 | 215 | if ( annotationtype ) { |
207 | 216 | if ( !parNode ) { |
208 | 217 | newPara(); |
— | — | @@ -274,7 +283,7 @@ |
275 | 284 | switch ( cnode.nodeType ) { |
276 | 285 | case Node.ELEMENT_NODE: |
277 | 286 | // Call a handler for the particular annotation node type |
278 | | - var annotationtype = this._getWikiDomAnnotationType( cnode.nodeName, true ); |
| 287 | + var annotationtype = this._getWikiDomAnnotationType( cnode, true ); |
279 | 288 | if ( annotationtype ) { |
280 | 289 | var res = this._convertHTMLAnnotation( cnode, offset, annotationtype ); |
281 | 290 | //console.log( 'res leaf: ' + JSON.stringify(res, null, 2)); |
— | — | @@ -332,7 +341,7 @@ |
333 | 342 | switch ( cnode.nodeType ) { |
334 | 343 | case Node.ELEMENT_NODE: |
335 | 344 | // Call a handler for the particular annotation node type |
336 | | - var annotationtype = this._getWikiDomAnnotationType(cnode.nodeName, true); |
| 345 | + var annotationtype = this._getWikiDomAnnotationType(cnode, true); |
337 | 346 | if ( annotationtype ) { |
338 | 347 | var res = this._convertHTMLAnnotation( cnode, offset, annotationtype ); |
339 | 348 | //console.log( 'res annotations 2: ' + JSON.stringify(res, null, 2)); |
— | — | @@ -389,13 +398,24 @@ |
390 | 399 | return out; |
391 | 400 | }; |
392 | 401 | |
| 402 | +/** |
| 403 | + * Convert HTML element attributes into WikiDom annotation data attributes. |
| 404 | + * |
| 405 | + * @param {Object} DOM node |
| 406 | + * @return {Object} data object |
| 407 | + */ |
393 | 408 | DOMConverter.prototype._HTMLPropertiesToWikiData = function ( elem ) { |
394 | 409 | var attribs = elem.attributes, |
| 410 | + name = elem.tagName.toLowerCase(); |
395 | 411 | out = {}; |
396 | 412 | for ( var i = 0, l = attribs.length; i < l; i++ ) { |
397 | 413 | var attrib = attribs.item(i), |
398 | 414 | key = attrib.name; |
399 | | - if ( key.match( /^data-json-/ ) ) { |
| 415 | + |
| 416 | + if ( this._HTMLPropertiesToWikiAttributesMap[name] && |
| 417 | + this._HTMLPropertiesToWikiAttributesMap[name][key] ) { |
| 418 | + out[this._HTMLPropertiesToWikiAttributesMap[name][key]] = attrib.value; |
| 419 | + } else if ( key.match( /^data-json-/ ) ) { |
400 | 420 | // strip data-json- prefix and decode |
401 | 421 | out[key.replace( /^data-json-/, '' )] = JSON.parse(attrib.value); |
402 | 422 | } else if ( key.match( /^data-/ ) ) { |
— | — | @@ -414,7 +434,15 @@ |
415 | 435 | } |
416 | 436 | return out; |
417 | 437 | }; |
| 438 | +// Attribute map html (tagName, attributeName) pairs to WikiDom names for the |
| 439 | +// same element |
| 440 | +DOMConverter.prototype._HTMLPropertiesToWikiAttributesMap = { |
| 441 | + a: { |
| 442 | + href: 'title' |
| 443 | + } |
| 444 | +}; |
418 | 445 | |
| 446 | + |
419 | 447 | // Quick HACK: define Node constants locally |
420 | 448 | // https://developer.mozilla.org/en/nodeType |
421 | 449 | var Node = { |
Index: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt |
— | — | @@ -592,11 +592,17 @@ |
593 | 593 | text = [{type: 'TEXT', value: "[" + linkCount + "]"}]; |
594 | 594 | linkCount++; |
595 | 595 | } |
596 | | - return [ { type: 'TAG', |
597 | | - name: 'a', |
598 | | - attribs: [['href', target]] } ] |
599 | | - .concat( text |
600 | | - , [{type: 'ENDTAG', name: 'a'}]); |
| 596 | + return [ |
| 597 | + { |
| 598 | + type: 'TAG', |
| 599 | + name: 'a', |
| 600 | + attribs: [ |
| 601 | + ['href', target], |
| 602 | + ['data-type', 'external'] |
| 603 | + ], |
| 604 | + } |
| 605 | + ].concat( text |
| 606 | + , [{type: 'ENDTAG', name: 'a'}]); |
601 | 607 | } |
602 | 608 | / "[" & { clearFlag('extlink'); return false; } |
603 | 609 | |
— | — | @@ -719,7 +725,9 @@ |
720 | 726 | var obj = { |
721 | 727 | type: 'TAG', |
722 | 728 | name: 'a', |
723 | | - attribs: [['data-type', 'internal']] |
| 729 | + attribs: [ |
| 730 | + ['data-type', 'internal'] |
| 731 | + ] |
724 | 732 | }; |
725 | 733 | obj.attribs.push(['href', target]); |
726 | 734 | if (ltext && ltext.length) { |