Index: trunk/extensions/LiquidThreads/i18n/Lqt.i18n.php |
— | — | @@ -191,6 +191,7 @@ |
192 | 192 | |
193 | 193 | // Quoting functionality |
194 | 194 | 'lqt-quote-intro' => 'On $2 at $3, [[User:$1]] wrote:', |
| 195 | + 'lqt-quote' => 'Quote this', |
195 | 196 | ); |
196 | 197 | |
197 | 198 | /** Message documentation (Message documentation) |
Index: trunk/extensions/LiquidThreads/lqt.css |
— | — | @@ -487,6 +487,7 @@ |
488 | 488 | .lqt-command-icon { |
489 | 489 | width: 1.5em; |
490 | 490 | height: 1.5em; |
| 491 | + margin-right: 0.2em; |
491 | 492 | } |
492 | 493 | |
493 | 494 | li.lqt-command-reply { |
— | — | @@ -536,6 +537,11 @@ |
537 | 538 | padding-right: 0.5em; |
538 | 539 | } |
539 | 540 | |
| 541 | +.lqt-header-quote { |
| 542 | + padding-left: 0.5em; |
| 543 | + padding-right: 0.5em; |
| 544 | +} |
| 545 | + |
540 | 546 | .lqt-thread-actions-trigger { |
541 | 547 | margin-bottom: 0; |
542 | 548 | } |
Index: trunk/extensions/LiquidThreads/icons/lqt-icon-quote.svg |
— | — | @@ -0,0 +1,74 @@ |
| 2 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 3 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
| 4 | +<svg |
| 5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
| 6 | + xmlns:cc="http://creativecommons.org/ns#" |
| 7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
| 8 | + xmlns:svg="http://www.w3.org/2000/svg" |
| 9 | + xmlns="http://www.w3.org/2000/svg" |
| 10 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
| 11 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
| 12 | + width="64px" |
| 13 | + height="64px" |
| 14 | + id="svg2383" |
| 15 | + sodipodi:version="0.32" |
| 16 | + inkscape:version="0.46" |
| 17 | + sodipodi:docname="lqt-icon-quote.svg" |
| 18 | + inkscape:output_extension="org.inkscape.output.svg.inkscape"> |
| 19 | + <defs |
| 20 | + id="defs2385"> |
| 21 | + <inkscape:perspective |
| 22 | + sodipodi:type="inkscape:persp3d" |
| 23 | + inkscape:vp_x="0 : 32 : 1" |
| 24 | + inkscape:vp_y="0 : 1000 : 0" |
| 25 | + inkscape:vp_z="64 : 32 : 1" |
| 26 | + inkscape:persp3d-origin="32 : 21.333333 : 1" |
| 27 | + id="perspective2391" /> |
| 28 | + </defs> |
| 29 | + <sodipodi:namedview |
| 30 | + id="base" |
| 31 | + pagecolor="#ffffff" |
| 32 | + bordercolor="#666666" |
| 33 | + borderopacity="1.0" |
| 34 | + inkscape:pageopacity="0.0" |
| 35 | + inkscape:pageshadow="2" |
| 36 | + inkscape:zoom="5.5" |
| 37 | + inkscape:cx="35.686073" |
| 38 | + inkscape:cy="23.995825" |
| 39 | + inkscape:current-layer="layer1" |
| 40 | + showgrid="true" |
| 41 | + inkscape:document-units="px" |
| 42 | + inkscape:grid-bbox="true" |
| 43 | + inkscape:window-width="738" |
| 44 | + inkscape:window-height="713" |
| 45 | + inkscape:window-x="20" |
| 46 | + inkscape:window-y="20" /> |
| 47 | + <metadata |
| 48 | + id="metadata2388"> |
| 49 | + <rdf:RDF> |
| 50 | + <cc:Work |
| 51 | + rdf:about=""> |
| 52 | + <dc:format>image/svg+xml</dc:format> |
| 53 | + <dc:type |
| 54 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
| 55 | + </cc:Work> |
| 56 | + </rdf:RDF> |
| 57 | + </metadata> |
| 58 | + <g |
| 59 | + id="layer1" |
| 60 | + inkscape:label="Layer 1" |
| 61 | + inkscape:groupmode="layer"> |
| 62 | + <text |
| 63 | + xml:space="preserve" |
| 64 | + style="font-size:82.23377990999998133px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#130a76;fill-opacity:1;stroke:#000000;stroke-width:0.81831366000000005px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Silom;-inkscape-font-specification:Silom Bold" |
| 65 | + x="-7.3537679" |
| 66 | + y="114.99871" |
| 67 | + id="text2393" |
| 68 | + transform="scale(0.8939972,1.1185717)"><tspan |
| 69 | + sodipodi:role="line" |
| 70 | + id="tspan2395" |
| 71 | + x="-7.3537679" |
| 72 | + y="114.99871" |
| 73 | + style="font-size:148.02081298999999603px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#130a76;fill-opacity:1;stroke:#000000;stroke-width:0.81831366000000005;stroke-opacity:1;font-family:Silom;-inkscape-font-specification:Silom Bold">”</tspan></text> |
| 74 | + </g> |
| 75 | +</svg> |
Index: trunk/extensions/LiquidThreads/icons/lqt-icon-quote.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/LiquidThreads/icons/lqt-icon-quote.png |
___________________________________________________________________ |
Name: svn:mime-type |
1 | 76 | + application/octet-stream |
Index: trunk/extensions/LiquidThreads/lqt.js |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | var footer_cmds = getElementsByClassName( container, '*', 'lqt_post' )[0]; |
16 | 16 | var query = '&lqt_method=reply&lqt_operand='+thread_id; |
17 | 17 | |
18 | | - liquidThreads.injectEditForm( query, container, footer_cmds.nextSibling ); |
| 18 | + liquidThreads.injectEditForm( query, container, footer_cmds.nextSibling, e.preload ); |
19 | 19 | |
20 | 20 | e.preventDefault(); |
21 | 21 | |
— | — | @@ -38,7 +38,7 @@ |
39 | 39 | return false; |
40 | 40 | }, |
41 | 41 | |
42 | | - 'injectEditForm' : function(query, container, before) { |
| 42 | + 'injectEditForm' : function(query, container, before, preload) { |
43 | 43 | var x = sajax_init_object(); |
44 | 44 | var url = wgServer+wgScript+'?title='+encodeURIComponent(wgPageName)+ |
45 | 45 | query+'&lqt_inline=1' |
— | — | @@ -48,6 +48,11 @@ |
49 | 49 | function() { |
50 | 50 | if (x.readyState != 4) |
51 | 51 | return; |
| 52 | + |
| 53 | + if ( liquidThreads.currentEditForm ) { |
| 54 | + var f = liquidThreads.currentEditForm; |
| 55 | + f.parentNode.removeChild( f ); |
| 56 | + } |
52 | 57 | |
53 | 58 | var result = x.responseText; |
54 | 59 | var replyDiv = document.createElement( 'div' ); |
— | — | @@ -59,9 +64,121 @@ |
60 | 65 | } else { |
61 | 66 | container.appendChild( replyDiv ); |
62 | 67 | } |
| 68 | + |
| 69 | + liquidThreads.currentEditForm = replyDiv; |
| 70 | + |
| 71 | + if (preload) { |
| 72 | + var textbox = document.getElementById( 'wpTextbox1' ); |
| 73 | + textbox.value = preload; |
| 74 | + } |
63 | 75 | }; |
64 | 76 | |
65 | 77 | x.send( null ); |
| 78 | + }, |
| 79 | + |
| 80 | + //From http://clipmarks.com/clipmark/CEFC94CB-94D6-4495-A7AA-791B7355E284/ |
| 81 | + 'insertAtCursor' : function(myField, myValue) { |
| 82 | + //IE support |
| 83 | + if (document.selection) { |
| 84 | + myField.focus(); |
| 85 | + sel = document.selection.createRange(); |
| 86 | + sel.text = myValue; |
| 87 | + } |
| 88 | + //MOZILLA/NETSCAPE support |
| 89 | + else if (myField.selectionStart || myField.selectionStart == '0') { |
| 90 | + var startPos = myField.selectionStart; |
| 91 | + var endPos = myField.selectionEnd; |
| 92 | + myField.value = myField.value.substring(0, startPos) |
| 93 | + + myValue |
| 94 | + + myField.value.substring(endPos, myField.value.length); |
| 95 | + } else { |
| 96 | + myField.value += myValue; |
| 97 | + } |
| 98 | + }, |
| 99 | + |
| 100 | + 'transformQuote' : function(quote) { |
| 101 | + var lines = quote.split("\n"); |
| 102 | + var newQuote = ''; |
| 103 | + |
| 104 | + for( var i = 0; i<lines.length; ++i ) { |
| 105 | + newQuote += "> "+lines[i]+"\n"; |
| 106 | + } |
| 107 | + |
| 108 | + return newQuote; |
| 109 | + }, |
| 110 | + |
| 111 | + 'getSelection' : function() { |
| 112 | + if (window.getSelection) { |
| 113 | + return window.getSelection().toString(); |
| 114 | + } else if (document.selection) { |
| 115 | + return document.selection.createRange().text; |
| 116 | + } else if (document.getSelection) { |
| 117 | + return document.getSelection(); |
| 118 | + } else { |
| 119 | + return ''; |
| 120 | + } |
| 121 | + }, |
| 122 | + |
| 123 | + 'doQuote' : function(e) { |
| 124 | + if (!e) e = window.event; |
| 125 | + e.preventDefault(); |
| 126 | + |
| 127 | + var button; |
| 128 | + if (e.target) button = e.target; |
| 129 | + else if (e.srcElement) button = e.srcElement; |
| 130 | + |
| 131 | + var text = liquidThreads.getSelection(); |
| 132 | + text = liquidThreads.transformQuote( text ); |
| 133 | + // TODO auto-generate context info and link. |
| 134 | + |
| 135 | + var textbox = document.getElementById( 'wpTextbox1' ); |
| 136 | + if (textbox) { |
| 137 | + liquidThreads.insertAtCursor( textbox, text ); |
| 138 | + } else { |
| 139 | + // Open the reply window |
| 140 | + var elem = button; |
| 141 | + |
| 142 | + // Keep walking up until we hit the thread node. |
| 143 | + while (elem.id.substr(0,13) != 'lqt_thread_id') { |
| 144 | + elem = elem.parentNode; |
| 145 | + } |
| 146 | + var post = getElementsByClassName( elem, 'div', 'lqt_post' )[0]; |
| 147 | + var replyLI = getElementsByClassName( post, 'li', 'lqt-command-reply' )[0]; |
| 148 | + var replyLink = replyLI.getElementsByTagName( 'a' )[0]; |
| 149 | + |
| 150 | + liquidThreads.handleReplyLink( { 'target':replyLink, 'preload':text } ); |
| 151 | + } |
| 152 | + |
| 153 | + return false; |
| 154 | + }, |
| 155 | + |
| 156 | + 'showQuoteButtons' : function() { |
| 157 | + var elems = getElementsByClassName( document, 'div', 'lqt-thread-header-rhs' ); |
| 158 | + var url = wgScriptPath+'/extensions/LiquidThreads/icons/lqt-icon-quote.png'; |
| 159 | + |
| 160 | + var length = elems.length; |
| 161 | + for( var i = 0; i<length; ++i ) { |
| 162 | + var quoteButton = document.createElement( 'span' ); |
| 163 | + quoteButton.className = 'lqt-header-quote'; |
| 164 | + |
| 165 | + var img = document.createElement( 'img' ); |
| 166 | + img.src = url; |
| 167 | + img.className = 'lqt-command-icon'; |
| 168 | + |
| 169 | + var text = wgLqtMessages['lqt-quote']; |
| 170 | + var textNode = document.createTextNode( text ); |
| 171 | + |
| 172 | + var link = document.createElement( 'a' ); |
| 173 | + link.href='#'; |
| 174 | + link.appendChild( img ); |
| 175 | + link.appendChild( textNode ); |
| 176 | + quoteButton.appendChild( link ); |
| 177 | + |
| 178 | + addHandler( quoteButton, 'click', liquidThreads.doQuote ); |
| 179 | + |
| 180 | + elems[i].insertBefore( quoteButton, elems[i].firstChild ); |
| 181 | + elems[i].insertBefore( document.createTextNode( '|' ), quoteButton.nextSibling ); |
| 182 | + } |
66 | 183 | } |
67 | 184 | } |
68 | 185 | |
— | — | @@ -89,5 +206,8 @@ |
90 | 207 | var newThreadLink = getElementsByClassName( document, 'a', 'lqt_start_discussion' )[0]; |
91 | 208 | |
92 | 209 | addHandler( newThreadLink, 'click', liquidThreads.handleNewLink ); |
| 210 | + |
| 211 | + // Show quote buttons |
| 212 | + liquidThreads.showQuoteButtons(); |
93 | 213 | } ); |
94 | 214 | |
Index: trunk/extensions/LiquidThreads/classes/LqtView.php |
— | — | @@ -366,24 +366,6 @@ |
367 | 367 | Xml::inputLabel( $subject_label, 'lqt_subject_field', 'lqt_subject_field', |
368 | 368 | 60, $subject, $attr ) . Xml::element( 'br' ); |
369 | 369 | } |
370 | | - |
371 | | - // Quote the original message if we're replying |
372 | | - if ( $edit_type == 'reply' ) { |
373 | | - global $wgContLang; |
374 | | - |
375 | | - $thread_article = new Post( $edit_applies_to->title() ); |
376 | | - |
377 | | - $quote_text = $thread_article->getContent(); |
378 | | - $timestamp = $edit_applies_to->created(); |
379 | | - $fTime = $wgContLang->time($timestamp); |
380 | | - $fDate = $wgContLang->date($timestamp); |
381 | | - $user = $edit_applies_to->author()->getName(); |
382 | | - |
383 | | - $quoteIntro = wfMsgForContent( 'lqt-quote-intro', $user, $fTime, $fDate ); |
384 | | - $quote_text = "$quoteIntro\n<blockquote>\n$quote_text\n</blockquote>\n"; |
385 | | - |
386 | | - $e->setPreloadedText( $quote_text ); |
387 | | - } |
388 | 370 | |
389 | 371 | $e->edit(); |
390 | 372 | |
— | — | @@ -639,17 +621,26 @@ |
640 | 622 | static function addJSandCSS() { |
641 | 623 | // Changed this to be static so that we can call it from |
642 | 624 | // wfLqtBeforeWatchlistHook. |
643 | | - global $wgJsMimeType, $wgScriptPath, $wgStyleVersion; // TODO globals. |
644 | 625 | global $wgOut; |
645 | | - $s = <<< HTML |
646 | | - <script type="{$wgJsMimeType}" src="{$wgScriptPath}/extensions/LiquidThreads/lqt.js"><!-- lqt js --></script> |
647 | | - <style type="text/css" media="screen, projection">/*<![CDATA[*/ |
648 | | - @import "{$wgScriptPath}/extensions/LiquidThreads/lqt.css?{$wgStyleVersion}"; |
649 | | - /*]]>*/</style> |
| 626 | + global $wgScriptPath, $wgStyleVersion; |
650 | 627 | |
651 | | -HTML; |
652 | | - $wgOut->addScript( $s ); |
| 628 | + $wgOut->addInlineScript( 'var wgLqtMessages = ' . self::exportJSLocalisation() . ';' ); |
| 629 | + $wgOut->addScriptFile( "{$wgScriptPath}/extensions/LiquidThreads/lqt.js" ); |
| 630 | + $wgOut->addExtensionStyle( "{$wgScriptPath}/extensions/LiquidThreads/lqt.css?{$wgStyleVersion}" ); |
653 | 631 | } |
| 632 | + |
| 633 | + static function exportJSLocalisation() { |
| 634 | + wfLoadExtensionMessages( 'LiquidThreads' ); |
| 635 | + |
| 636 | + $messages = array( 'lqt-quote-intro', 'lqt-quote' ); |
| 637 | + $data = array(); |
| 638 | + |
| 639 | + foreach( $messages as $msg ) { |
| 640 | + $data[$msg] = wfMsgNoTrans( $msg ); |
| 641 | + } |
| 642 | + |
| 643 | + return json_encode( $data ); |
| 644 | + } |
654 | 645 | |
655 | 646 | /* @return False if the article and revision do not exist. The HTML of the page to |
656 | 647 | * display if it exists. Note that this impacts the state out OutputPage by adding |