r90491 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90490‎ | r90491 | r90492 >
Date:22:32, 20 June 2011
Author:brion
Status:deferred
Tags:
Comment:
ParserPlayground: reworking mode select toolbar, inspector setup
Modified paths:
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.css (modified) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.js (modified) (history)
  • /trunk/extensions/ParserPlayground/modules/images (added) (history)
  • /trunk/extensions/ParserPlayground/modules/images/inspector-active.png (added) (history)
  • /trunk/extensions/ParserPlayground/modules/images/inspector-active.svg (added) (history)
  • /trunk/extensions/ParserPlayground/modules/images/inspector.png (added) (history)
  • /trunk/extensions/ParserPlayground/modules/images/inspector.svg (added) (history)

Diff [purge]

Index: trunk/extensions/ParserPlayground/modules/images/inspector-active.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/extensions/ParserPlayground/modules/images/inspector-active.png
___________________________________________________________________
Added: svn:mime-type
11 + image/png
Index: trunk/extensions/ParserPlayground/modules/images/inspector.svg
@@ -0,0 +1,74 @@
 2+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 3+<!-- Created with Inkscape (http://www.inkscape.org/) -->
 4+
 5+<svg
 6+ xmlns:dc="http://purl.org/dc/elements/1.1/"
 7+ xmlns:cc="http://creativecommons.org/ns#"
 8+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 9+ xmlns:svg="http://www.w3.org/2000/svg"
 10+ xmlns="http://www.w3.org/2000/svg"
 11+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 12+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 13+ width="22"
 14+ height="22"
 15+ id="svg2985"
 16+ version="1.1"
 17+ inkscape:version="0.48.1 r9760"
 18+ sodipodi:docname="inspector-active.svg"
 19+ inkscape:export-filename="/var/www/trunk/extensions/CodeEditor/images/code-selected.png"
 20+ inkscape:export-xdpi="90"
 21+ inkscape:export-ydpi="90">
 22+ <defs
 23+ id="defs2987" />
 24+ <sodipodi:namedview
 25+ id="base"
 26+ pagecolor="#ffffff"
 27+ bordercolor="#666666"
 28+ borderopacity="1.0"
 29+ inkscape:pageopacity="0.0"
 30+ inkscape:pageshadow="2"
 31+ inkscape:zoom="11.197802"
 32+ inkscape:cx="-16.595683"
 33+ inkscape:cy="19.57213"
 34+ inkscape:current-layer="layer1"
 35+ showgrid="true"
 36+ inkscape:grid-bbox="true"
 37+ inkscape:document-units="px"
 38+ inkscape:window-width="1920"
 39+ inkscape:window-height="1056"
 40+ inkscape:window-x="1920"
 41+ inkscape:window-y="24"
 42+ inkscape:window-maximized="1" />
 43+ <metadata
 44+ id="metadata2990">
 45+ <rdf:RDF>
 46+ <cc:Work
 47+ rdf:about="">
 48+ <dc:format>image/svg+xml</dc:format>
 49+ <dc:type
 50+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 51+ <dc:title></dc:title>
 52+ </cc:Work>
 53+ </rdf:RDF>
 54+ </metadata>
 55+ <g
 56+ id="layer1"
 57+ inkscape:label="Layer 1"
 58+ inkscape:groupmode="layer"
 59+ transform="translate(0,-10)">
 60+ <rect
 61+ style="fill:none;stroke:#000000;stroke-opacity:1"
 62+ id="rect3826"
 63+ width="15.360157"
 64+ height="5.6261044"
 65+ x="3.3042197"
 66+ y="13.24632"
 67+ rx="0.5" />
 68+ <path
 69+ style="fill:#000000;stroke:#ffffff;stroke-width:1.35400056999999996px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
 70+ d="m 7.8190728,28.218242 0,-12.614219 8.9202452,7.883887 -2.955534,1.391511 1.750094,2.611078 -3.040418,1.602107 -1.540246,-2.675053 z"
 71+ id="path3828"
 72+ inkscape:connector-curvature="0"
 73+ sodipodi:nodetypes="cccccccc" />
 74+ </g>
 75+</svg>
Index: trunk/extensions/ParserPlayground/modules/images/inspector.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/extensions/ParserPlayground/modules/images/inspector.png
___________________________________________________________________
Added: svn:mime-type
176 + image/png
Index: trunk/extensions/ParserPlayground/modules/images/inspector-active.svg
@@ -0,0 +1,82 @@
 2+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 3+<!-- Created with Inkscape (http://www.inkscape.org/) -->
 4+
 5+<svg
 6+ xmlns:dc="http://purl.org/dc/elements/1.1/"
 7+ xmlns:cc="http://creativecommons.org/ns#"
 8+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 9+ xmlns:svg="http://www.w3.org/2000/svg"
 10+ xmlns="http://www.w3.org/2000/svg"
 11+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 12+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 13+ width="22"
 14+ height="22"
 15+ id="svg2985"
 16+ version="1.1"
 17+ inkscape:version="0.48.1 r9760"
 18+ sodipodi:docname="comment.svg"
 19+ inkscape:export-filename="/var/www/trunk/extensions/CodeEditor/images/code-selected.png"
 20+ inkscape:export-xdpi="90"
 21+ inkscape:export-ydpi="90">
 22+ <defs
 23+ id="defs2987" />
 24+ <sodipodi:namedview
 25+ id="base"
 26+ pagecolor="#ffffff"
 27+ bordercolor="#666666"
 28+ borderopacity="1.0"
 29+ inkscape:pageopacity="0.0"
 30+ inkscape:pageshadow="2"
 31+ inkscape:zoom="11.197802"
 32+ inkscape:cx="-16.595683"
 33+ inkscape:cy="19.57213"
 34+ inkscape:current-layer="layer1"
 35+ showgrid="true"
 36+ inkscape:grid-bbox="true"
 37+ inkscape:document-units="px"
 38+ inkscape:window-width="1920"
 39+ inkscape:window-height="1056"
 40+ inkscape:window-x="1920"
 41+ inkscape:window-y="24"
 42+ inkscape:window-maximized="1" />
 43+ <metadata
 44+ id="metadata2990">
 45+ <rdf:RDF>
 46+ <cc:Work
 47+ rdf:about="">
 48+ <dc:format>image/svg+xml</dc:format>
 49+ <dc:type
 50+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 51+ <dc:title></dc:title>
 52+ </cc:Work>
 53+ </rdf:RDF>
 54+ </metadata>
 55+ <g
 56+ id="layer1"
 57+ inkscape:label="Layer 1"
 58+ inkscape:groupmode="layer"
 59+ transform="translate(0,-10)">
 60+ <rect
 61+ style="opacity:0.50000000000000000;fill:#ffffff;fill-opacity:1;stroke:#808080;stroke-opacity:1"
 62+ id="rect3188"
 63+ width="21"
 64+ height="21"
 65+ x="0.53581941"
 66+ y="10.567223"
 67+ rx="3" />
 68+ <rect
 69+ style="fill:none;stroke:#2a7fff;stroke-opacity:1"
 70+ id="rect3826"
 71+ width="15.360157"
 72+ height="5.6261044"
 73+ x="3.3042197"
 74+ y="13.24632"
 75+ rx="0.5" />
 76+ <path
 77+ style="fill:#2a7fff;stroke:#ffffff;stroke-width:1.35400057px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 78+ d="m 7.8190728,28.218242 0,-12.614219 8.9202452,7.883887 -2.955534,1.391511 1.750094,2.611078 -3.040418,1.602107 -1.540246,-2.675053 z"
 79+ id="path3828"
 80+ inkscape:connector-curvature="0"
 81+ sodipodi:nodetypes="cccccccc" />
 82+ </g>
 83+</svg>
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.css
@@ -1,7 +1,9 @@
2 -#mw-parser-popup .parseNode {
 2+#mw-parser-popup .parseNode,
 3+#mw-parser-inspector .parseNode {
34 border: solid 1px transparent;
45 }
5 -#mw-parser-popup .parseNodeHighlight {
 6+#mw-parser-popup .parseNodeHighlight,
 7+#mw-parser-inspector .parseNodeHighlight {
68 border: solid 1px blue;
79 }
810
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.js
@@ -40,12 +40,13 @@
4141 $('#mw-parser-popup').remove();
4242 // line-height is needed to compensate for oddity in WikiEditor extension, which zeroes the line-height on a parent container
4343 var box = $('#wpTextbox1');
44 - var target = $('<div id="mw-parser-popup" style="position: relative; z-index: 9999; overflow: auto; background: white"><div class="editor" style="line-height: 1.5em; top: 0px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray">' + inside + '</div></div>').insertAfter(box);
 44+ var target = $('<div id="mw-parser-popup" style="width: 100%; overflow-y: auto; background: white"><div class="editor" style="line-height: 1.5em; top: 0px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray">' + inside + '</div></div>').insertAfter(box);
4545 $('#wpTextbox1').css('display', 'none');
4646
4747 onResize = function() {
48 - target.width(box.width())
49 - .height(box.height());
 48+ //target.width(box.width())
 49+ // .height(box.height());
 50+ target.height(box.height());
5051 };
5152 onResize();
5253 return target;
@@ -85,15 +86,17 @@
8687 callback(aNode, bNode);
8788 };
8889 a.delegate('.parseNode', 'mouseenter', function(event) {
 90+ $('.parseNodeHighlight').removeClass('parseNodeHighlight');
8991 match(this, function(node, other) {
9092 $(node).addClass('parseNodeHighlight');
9193 $(other).addClass('parseNodeHighlight');
9294 });
 95+ event.preventDefault();
 96+ return false;
9397 }).delegate('.parseNode', 'mouseleave', function(event) {
94 - match(this, function(node, other) {
95 - $(node).removeClass('parseNodeHighlight');
96 - $(other).removeClass('parseNodeHighlight');
97 - });
 98+ $('.parseNodeHighlight').removeClass('parseNodeHighlight');
 99+ event.preventDefault();
 100+ return false;
98101 }).delegate('.parseNode', 'click', function(event) {
99102 match(this, function(node, other) {
100103 if (other) {
@@ -118,61 +121,16 @@
119122 };
120123
121124 var addParserModes = function(modes, parserClass, className, detail) {
122 - detail = detail || '';
123 - modes[className] = {
124 - label: className,
125 - desc: '<p>Showing the page rendered with ' + className + '.</p>' + detail,
126 - render: function(src, dest) {
127 - var parser = new parserClass();
128 - parser.parseToTree(src, function(tree, err) {
129 - parser.treeToHtml(tree, function(node, err) {
130 - dest.append(node);
131 - });
132 - });
133 - }
 125+ modes[className] = {
 126+ 'label': className,
 127+ 'action': {
 128+ 'type': 'callback',
 129+ 'execute': function( context ) {
 130+ context.parserPlayground.parser = new parserClass();
 131+ context.parserPlayground.fn.initDisplay();
 132+ }
 133+ }
134134 };
135 - modes[className + '-tree'] = {
136 - label: className + ' tree',
137 - desc: '<p>Showing the page broken down to parse tree with ' + className + '.</p>' + detail,
138 - render: function(src, dest) {
139 - var parser = new parserClass();
140 - parser.parseToTree(src, function(tree, err) {
141 - $(dest).nodeTree( tree );
142 - });
143 - }
144 - };
145 - modes[className + '-roundtrip'] = {
146 - label: className + ' round-trip',
147 - desc: '<p>Showing the page as parsed, then returned to source via ' + className + '.</p>' + detail,
148 - render: function(src, dest) {
149 - var parser = new parserClass();
150 - parser.parseToTree(src, function(tree, err) {
151 - parser.treeToSource(tree, function(src2, err) {
152 - var target = $('<div style="white-space: pre-wrap; font-family: monospace">').appendTo(dest);
153 - target.html(diffString(src, src2));
154 - });
155 - });
156 - }
157 - };
158 - modes[className + '-inspect'] = {
159 - label: className + ' inspect',
160 - desc: '<p>Shows ' + className + '\'s HTML output and parse tree side-by-side.</p>' + detail,
161 - render: function(src, dest) {
162 - var parser = new parserClass();
163 - var treeMap = new HashMap(), renderMap = new HashMap();
164 - parser.parseToTree(src, function(tree, err) {
165 - var target = makeInspectorColumns(dest);
166 - var left = target.find('.left'), right = target.find('.right');
167 - left.nodeTree( tree, function( node, el ) {
168 - treeMap.put( node, el );
169 - });
170 - parser.treeToHtml(tree, function(node, err) {
171 - right.append(node);
172 - setupInspector(left, right, treeMap, renderMap);
173 - }, renderMap);
174 - });
175 - }
176 - };
177135 };
178136
179137 $(document).ready( function() {
@@ -180,60 +138,123 @@
181139 var editor = $('#wpTextbox1');
182140 if (editor.length > 0 && typeof $.fn.wikiEditor === 'function') {
183141 //$('#wpTextbox1').bind('wikiEditor-toolbar-buildSection-main', function() {
184 - var modes = {
185 - 'source': {
186 - label: 'Source',
187 - desc: 'Showing the page\'s original wikitext source code, as you are used to editing it.',
188 - render: false
189 - }
 142+ var listItems = {
 143+ 'sourceView': {
 144+ 'label': 'Source',
 145+ 'action': {
 146+ 'type': 'callback',
 147+ 'execute': function( context ) {
 148+ context.parserPlayground.parser = undefined;
 149+ context.parserPlayground.tree = undefined;
 150+ context.parserPlayground.fn.hide();
 151+ }
 152+ }
 153+ }
190154 };
191 - addParserModes(modes, MediaWikiParser, 'MediaWikiParser');
192 - addParserModes(modes, FakeParser, 'FakeParser');
193 - addParserModes(modes, PegParser, 'PegParser', '<p>Peg-based parser plus FakeParser\'s output. <a href="http://pegjs.majda.cz/documentation">pegjs documentation</a>; edit and reselect to reparse with updated parser</p>');
 155+ addParserModes(listItems, MediaWikiParser, 'MediaWikiParser');
 156+ addParserModes(listItems, FakeParser, 'FakeParser');
 157+ addParserModes(listItems, PegParser, 'PegParser', '<p>Peg-based parser plus FakeParser\'s output. <a href="http://pegjs.majda.cz/documentation">pegjs documentation</a>; edit and reselect to reparse with updated parser</p>');
194158
195159 window.setTimeout(function() {
196 - // Great, now let's hook the booklet buttons... (explicit callbacks would be better)
197 - var hook = function(key, callback) {
198 - // using live since they haven't been created yet...
199 - // 'mouseup' as a hack since the upstream click handler cancels other event handlers
200 - $('#wikiEditor-ui-toolbar .sections .section-parser .index div[rel=' + key + ']').live('mouseup', callback);
201 - };
202 - var pages = {};
203 - $.each(modes, function(name, mode) {
204 - pages[name] = {
205 - 'layout': 'table',
206 - 'label': mode.label,
207 - 'rows': [
208 - {
209 - 'desc': { 'html': mode.desc }
 160+ var context = editor.data('wikiEditor-context');
 161+ context.parserPlayground = {
 162+ parser: new FakeParser(),
 163+ tree: undefined,
 164+ useInspector: true,
 165+ fn: {
 166+ initDisplay: function() {
 167+ if (context.$parserContainer) {
 168+ context.parserPlayground.fn.hide();
210169 }
211 - ]
212 - };
213 - var render = mode.render;
214 - hook(name, function() {
215 - $('#pegparser-source').hide(); // it'll reshow; others won't need it
216 - if (mode.render) {
217 - var target = makeMagicBox('');
 170+ var $target = makeMagicBox('');
 171+ $('#mw-parser-inspector').remove();
 172+ var $inspector = $('<div id="mw-parser-inspector" style="position: relative; width: 100%; overflow-y: auto; height: 200px"></div>');
 173+ $inspector.insertAfter($target);
 174+ if (!context.parserPlayground.useInspector) {
 175+ $inspector.hide();
 176+ }
 177+
 178+ context.$parserContainer = $target;
 179+ context.$parserInspector = $inspector;
 180+
218181 var src = $('#wpTextbox1').val();
219 - var dest = target.find('div');
220 - render(src, dest);
221 - } else {
222 - $('#mw-parser-popup').remove();
223 - onResize = null;
224 - $('#wpTextbox1').css('display', 'block');
225 - }
226 - });
227 - });
228 - editor.wikiEditor( 'addToToolbar', {
229 - 'sections': {
230 - 'parser': {
231 - 'label': 'Parser',
232 - 'type': 'booklet',
233 - 'pages': pages
 182+ var $dest = $target.find('div');
 183+
 184+ var parser = context.parserPlayground.parser;
 185+ var treeMap = context.parserPlayground.treeMap = new HashMap(),
 186+ renderMap = new HashMap();
 187+ parser.parseToTree(src, function(tree, err) {
 188+ context.parserPlayground.tree = tree;
 189+ if (context.parserPlayground.useInspector) {
 190+ $inspector.nodeTree( tree, function( node, el ) {
 191+ treeMap.put( node, el );
 192+ });
 193+ }
 194+ parser.treeToHtml(tree, function(node, err) {
 195+ $dest.append(node);
 196+ setupInspector($target, $inspector, renderMap, treeMap);
 197+ }, renderMap);
 198+ });
 199+ },
 200+ hide: function() {
 201+ $('#pegparser-source').hide(); // it'll reshow; others won't need it
 202+ context.$iframe = undefined;
 203+ context.$parserContainer.remove();
 204+ context.$parserContainer = undefined;
 205+ context.$parserInspector.remove();
 206+ context.$parserInspector = undefined;
 207+ context.$textarea.show();
 208+ },
 209+ toggleInspector: function() {
 210+ if (context.parserPlayground.useInspector) {
 211+ context.parserPlayground.useInspector = false;
 212+ context.$parserInspector.hide();
 213+ } else if ( context.parserPlayground.parser ) {
 214+ context.parserPlayground.useInspector = true;
 215+ context.$parserInspector.empty().show();
 216+ context.$parserInspector.nodeTree( context.parserPlayground.tree, function( node, el ) {
 217+ context.parserPlayground.treeMap.put( node, el );
 218+ });
 219+ }
 220+ var target = 'img.tool[rel=inspector]';
 221+ var $img = context.modules.toolbar.$toolbar.find( target );
 222+ $img.attr('src', context.parserPlayground.fn.inspectorToolbarIcon());
 223+ },
 224+ inspectorToolbarIcon: function() {
 225+ // When loaded as a gadget, one may need to override the wiki's own assets path.
 226+ var iconPath = mw.config.get('wgParserPlaygroundAssetsPath', mw.config.get('wgExtensionAssetsPath')) + '/ParserPlayground/modules/images/';
 227+ return iconPath + (context.parserPlayground.useInspector ? 'inspector-active.png' : 'inspector.png');
234228 }
235229 }
236 - } );
237 -
 230+ }
 231+ editor.wikiEditor( 'addToToolbar', {
 232+ 'sections': {
 233+ 'richedit': {
 234+ 'label': 'Rich editor',
 235+ 'type': 'toolbar',
 236+ 'groups': {
 237+ 'mode': {
 238+ 'tools': {
 239+ 'mode': {
 240+ 'label': 'Mode',
 241+ 'type': 'select',
 242+ 'list': listItems
 243+ },
 244+ 'inspector': {
 245+ 'label': 'Toggle inspector',
 246+ 'type': 'button',
 247+ 'icon': context.parserPlayground.fn.inspectorToolbarIcon(),
 248+ 'action': {
 249+ 'type': 'callback',
 250+ 'execute': context.parserPlayground.fn.toggleInspector
 251+ }
 252+ }
 253+ }
 254+ }
 255+ }
 256+ }
 257+ }
 258+ } );
238259 }, 500 );
239260 } else {
240261 mw.log('No wiki editor');

Status & tagging log