Apply an empty-state to pages with the new topic tool enabled

This includes the dtrepliedto URL functionality from
I3f81e4d77faed367606e47678b8896051982359d.

Bug: T274831
Bug: T274832
Bug: T277329
Change-Id: I035d04f30c8312b0cb42902d3bf940df1482ffb3
This commit is contained in:
David Lynch 2021-07-29 01:12:10 -05:00
parent d4f4e49c7e
commit 91af0594b5
11 changed files with 299 additions and 23 deletions

View file

@ -380,6 +380,7 @@
"ParserAfterParse": "parser",
"ParserAfterTidy": "parser",
"ParserOptionsRegister": "parser",
"BeforeDisplayNoArticleText": "page",
"BeforePageDisplay": "page",
"GetActionName": "page",
"OutputPageBeforeHTML": "page",

View file

@ -5,6 +5,15 @@
"discussiontools": "Discussion tools",
"discussiontools-defaultsummary-reply": "Reply",
"discussiontools-desc": "Tools to enhance discussion pages.",
"discussiontools-emptystate-button": "Start a discussion",
"discussiontools-emptystate-desc": "You can use this talk page to start a discussion with others about how to improve [[{{ARTICLESPACE}}:{{PAGENAME}}|{{PAGENAME}}]]. [[{{MediaWiki:discussiontools-emptystate-link-talkpages}}|Learn more about how these pages are used]].",
"discussiontools-emptystate-desc-self": "People on {{SITENAME}} can use this page to post a public message for you and you will be notified when they do. [[{{MediaWiki:discussiontools-emptystate-link-userpage}}|Learn more about this page]].",
"discussiontools-emptystate-desc-user": "You can use this talk page to start a discussion with [[{{ARTICLESPACE}}:{{PAGENAME}}|{{PAGENAME}}]] that will be public for others to see. [[{{MediaWiki:discussiontools-emptystate-link-userpage}}|Learn more about how these pages are used]].",
"discussiontools-emptystate-link-talkpages": "mediawikiwiki:Special:MyLanguage/Help:Talk_pages",
"discussiontools-emptystate-link-userpage": "mediawikiwiki:Special:MyLanguage/Help:User_page",
"discussiontools-emptystate-title": "Start a discussion about [[{{ARTICLESPACE}}:{{PAGENAME}}|{{PAGENAME}}]]",
"discussiontools-emptystate-title-self": "Welcome to your talk page",
"discussiontools-emptystate-title-user": "Start a discussion with [[{{ARTICLESPACE}}:{{PAGENAME}}|{{PAGENAME}}]]",
"discussiontools-error-comment-conflict": "Your comment could not be saved, because someone else commented at the same time as you. Please try again, or reload the page to view the latest comments.",
"discussiontools-error-comment-disappeared": "Could not find the comment you're replying to on the page. It might have been deleted or moved to another page. Please reload the page and try again.",
"discussiontools-error-comment-is-transcluded": "The \"{{int:discussiontools-replylink}}\" link cannot be used to reply to this comment. To reply, please use the full page editor by clicking \"$1\".",

View file

@ -14,6 +14,15 @@
"discussiontools": "{{name}}",
"discussiontools-defaultsummary-reply": "Default edit summary for a reply.\n\n'''Note that this is a noun (''a reply''), not a verb (''to reply''). Alternatively you can use a past tense verb if that's more natural in your language.'''",
"discussiontools-desc": "{{desc\n| name = DiscussionTools\n| url = https://www.mediawiki.org/wiki/Extension:DiscussionTools\n}}",
"discussiontools-emptystate-button": "Label for add new topic button on empty talk pages.",
"discussiontools-emptystate-desc": "Description shown on empty talk pages of the purpose of talk pages.",
"discussiontools-emptystate-desc-self": "Description shown to the user of the purpose of their own talk page if it's empty.",
"discussiontools-emptystate-desc-user": "Description shown on empty user talk pages.",
"discussiontools-emptystate-link-talkpages": "{{notranslate}}\nLink to page describing what talk pages are.\n\nUsed in:\n* {{msg-mw|discussiontools-emptystate-desc}}.\n\nTranslate to a title where most wikis in the language you're translating to have one such help page; if they don't have one, you can use [[mw:Special:MyLanguage/Help:Talk_pages]] as target.",
"discussiontools-emptystate-link-userpage": "{{notranslate}}\nLink to page describing what user pages are.\n\nUsed in:\n* {{msg-mw|discussiontools-emptystate-desc-self}} and {{msg-mw|discussiontools-emptystate-desc-user}}.\n\nTranslate to a title where most wikis in the language you're translating to have one such help page; if they don't have one, you can use [[mw:Special:MyLanguage/Help:User_page]] as target.",
"discussiontools-emptystate-title": "Heading shown on empty talk pages",
"discussiontools-emptystate-title-self": "Heading shown on the user's own empty talk page",
"discussiontools-emptystate-title-user": "Heading shown on empty user talk pages",
"discussiontools-error-comment-conflict": "Error message of a comment conflict.\n\nSimilar messages:\n* {{msg-mw|visualeditor-editconflict}}\n* {{msg-mw|twocolconflict-split-tour-dialog-message-single-column-view}}\n* {{msg-mw|discussiontools-error-comment-disappeared}}",
"discussiontools-error-comment-disappeared": "Error message.",
"discussiontools-error-comment-is-transcluded": "Error message. Parameter: $1 text of the 'Edit'/'Edit source' tab",

119
images/emptystate.svg Normal file
View file

@ -0,0 +1,119 @@
<svg width="332" height="221" viewBox="0 0 332 221" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.2" d="M293.371 94.0744C297.765 101.686 305.531 106.109 318.083 104.918L315.274 99.9616C322.938 95.5365 325.559 85.7261 321.127 78.0495C316.694 70.373 306.888 67.7372 299.224 72.1623C291.559 76.5874 288.939 86.3978 293.371 94.0744Z" fill="#00AF89"/>
<line x1="299.732" y1="81.5005" x2="303.956" y2="81.5005" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="307.655" y1="81.5005" x2="315.274" y2="81.5005" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="299.732" y1="86.4121" x2="308.483" y2="86.4121" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="312.181" y1="86.4121" x2="315.274" y2="86.4121" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="299.732" y1="91.3232" x2="301.693" y2="91.3232" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="305.391" y1="91.3232" x2="315.273" y2="91.3232" stroke="white" stroke-width="2" stroke-linecap="round"/>
<path opacity="0.2" d="M58.1117 201.334C53.7173 208.945 45.9514 213.368 33.3996 212.177L36.2088 207.221C28.5443 202.796 25.9238 192.986 30.3559 185.309C34.788 177.633 44.5942 174.997 52.2587 179.422C59.9233 183.847 62.5437 193.658 58.1117 201.334Z" fill="#00AF89"/>
<line x1="36.7324" y1="188.5" x2="40.9565" y2="188.5" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="44.6548" y1="188.5" x2="52.2738" y2="188.5" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="36.7324" y1="193.412" x2="45.4831" y2="193.412" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="49.1812" y1="193.412" x2="52.2736" y2="193.412" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="36.7324" y1="198.323" x2="38.6932" y2="198.323" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="42.3906" y1="198.323" x2="52.2729" y2="198.323" stroke="white" stroke-width="2" stroke-linecap="round"/>
<line x1="268.916" y1="13.8618" x2="268.916" y2="24.646" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<line x1="263.614" y1="19.0811" x2="274.398" y2="19.0811" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<line x1="304.967" y1="151.703" x2="304.967" y2="162.487" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<line x1="299.665" y1="156.923" x2="310.449" y2="156.923" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<line x1="6.80176" y1="120.954" x2="6.80176" y2="131.738" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<line x1="1.5" y1="126.173" x2="12.2841" y2="126.173" stroke="#C8CCD1" stroke-width="3" stroke-linecap="round"/>
<circle cx="160" cy="110" r="110" fill="#F8F9FA"/>
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="50" y="0" width="220" height="220">
<circle cx="160" cy="110" r="110" fill="#F8F9FA"/>
</mask>
<g mask="url(#mask0)">
<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M200.166 124.51C198.978 123.807 197.445 124.201 196.742 125.389C196.039 126.578 196.433 128.111 197.622 128.814C207.135 134.438 211.228 141.567 212.119 149.296C213.031 157.197 210.631 166.044 206.445 174.964C199.491 189.785 188.062 203.937 180.698 213.054L180.698 213.055C179.181 214.933 177.837 216.598 176.739 218.01C175.962 219.012 176.057 220.437 176.961 221.326C177.865 222.215 179.291 222.287 180.28 221.493L219.787 189.757C228.627 190.04 242.245 185.936 242.909 167.08C236.076 165.977 222.313 168.272 217.847 184.903L194.332 203.791C200.206 195.944 206.488 186.645 210.972 177.088C215.328 167.803 218.152 157.958 217.086 148.723C216.001 139.317 210.916 130.865 200.166 124.51Z" fill="#00AF89"/>
<path d="M200.519 81.6558C194.321 89.9424 187.792 110.75 211.267 127.689C218.192 118.325 225.739 96.0087 200.519 81.6558Z" fill="#7EA2EC"/>
<path d="M165.542 122.076C171.606 130.462 189.523 142.893 212.686 125.531C205.811 116.131 186.757 102.278 165.542 122.076Z" fill="#7EA2EC"/>
<path d="M192.803 164.721C202.855 162.264 221.122 150.351 213.768 122.354C202.469 125.18 182.458 137.61 192.803 164.721Z" fill="#7EA2EC"/>
<path d="M243.294 153.216C243.345 142.867 236.21 122.26 207.265 122.614C207.271 134.261 214.485 156.687 243.294 153.216Z" fill="#7EA2EC"/>
<path d="M249.617 102.173C239.808 98.8746 218.002 99.1761 209.248 126.768C220.308 130.421 243.864 130.615 249.617 102.173Z" fill="#7EA2EC"/>
<g filter="url(#filter0_d)">
<path d="M223.937 132.013C219.944 138.928 212.888 142.947 201.484 141.865L204.036 137.362C197.072 133.341 194.691 124.427 198.718 117.452C202.745 110.478 211.655 108.083 218.619 112.103C225.583 116.124 227.964 125.038 223.937 132.013Z" fill="white"/>
</g>
<line x1="203.732" y1="120.5" x2="207.956" y2="120.5" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="211.655" y1="120.5" x2="219.274" y2="120.5" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="203.732" y1="125.412" x2="212.483" y2="125.412" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="216.181" y1="125.412" x2="219.274" y2="125.412" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="203.732" y1="130.323" x2="205.693" y2="130.323" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="209.391" y1="130.323" x2="219.273" y2="130.323" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M143.687 231.614C142.819 232.687 141.245 232.854 140.171 231.985C120.31 215.921 110.307 197.818 105.589 177.971C97.6019 178.38 84 174.617 84 156.13C89.0621 155.482 98.1735 157.043 103.361 165.891C102.229 157.572 101.816 148.977 101.816 140.125C101.816 138.744 102.935 137.625 104.316 137.625C105.697 137.625 106.816 138.744 106.816 140.125C106.816 151.443 107.501 162.207 109.502 172.427C113.106 163.128 121.551 161.538 126 162.1C126 175.031 117.279 178.64 110.989 178.974C115.71 197.112 125.223 213.464 143.316 228.098C144.389 228.966 144.555 230.54 143.687 231.614Z" fill="#00AF89"/>
<circle cx="102.773" cy="99.5193" r="27.4031" fill="#FFCC33"/>
<circle cx="113.883" cy="118.776" r="27.4031" fill="#FFCC33"/>
<circle cx="90.1829" cy="118.776" r="27.4031" fill="#FFCC33"/>
<path d="M86.8501 121.738C90.9235 125.071 97.3167 126.922 102.774 126.922C117.908 126.922 130.177 114.654 130.177 99.5193C130.177 84.385 117.908 72.1162 102.774 72.1162C89.1524 72.1162 77.8523 82.0545 75.729 95.0756" stroke="#F8F9FA" stroke-width="2" stroke-linecap="round"/>
<path d="M130.547 97.0197C137.076 102.028 141.286 109.91 141.286 118.776C141.286 133.91 129.017 146.179 113.883 146.179C98.7483 146.179 86.4795 133.91 86.4795 118.776C86.4795 107.886 92.8316 98.4796 102.033 94.0601" stroke="#F8F9FA" stroke-width="2" stroke-linecap="round"/>
<path d="M101.663 143.666C98.1708 145.279 94.2819 146.179 90.1829 146.179C75.0486 146.179 62.7798 133.91 62.7798 118.776C62.7798 103.641 75.0486 91.3726 90.1829 91.3726C105.317 91.3726 117.586 103.641 117.586 118.776C117.586 119.904 117.518 121.016 117.385 122.108" stroke="#F8F9FA" stroke-width="2" stroke-linecap="round"/>
<path d="M86.4795 122.108C86.4795 103.445 96.8482 95.8162 102.033 94.335C115.956 100.852 118.203 116.06 117.586 122.849C114.623 124.701 107.587 126.922 101.292 126.922C96.2557 126.922 89.3186 123.713 86.4795 122.108Z" fill="white"/>
<g filter="url(#filter1_d)">
<path d="M84.947 114.878C86.7388 124.358 93.3485 131.726 107.212 134.965L106.101 128.811C115.977 126.945 122.518 117.68 120.711 108.119C118.903 98.5569 109.433 92.3188 99.5567 94.1854C89.6808 96.052 83.1398 105.316 84.947 114.878Z" fill="white"/>
</g>
<line x1="93.9043" y1="105.805" x2="99.025" y2="105.805" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="102.968" y1="105.805" x2="111.973" y2="105.805" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="93.9043" y1="111.424" x2="104.204" y2="111.424" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="108.146" y1="111.424" x2="111.973" y2="111.424" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="93.9043" y1="117.043" x2="96.4357" y2="117.043" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="100.377" y1="117.043" x2="111.972" y2="117.043" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M159.305 107.717C160.685 107.717 161.805 108.837 161.805 110.217V165.141C166.689 156.242 175.621 154.679 180.539 155.31C180.539 171.605 169.488 175.914 161.805 176.17V227.541C161.805 228.922 160.685 230.041 159.305 230.041C157.924 230.041 156.805 228.922 156.805 227.541V161.568C149.144 161.783 136.722 157.98 136.722 140.704C142.137 140.009 152.418 141.974 156.805 153.464V110.217C156.805 108.837 157.924 107.717 159.305 107.717Z" fill="#00AF89"/>
<circle cx="159.544" cy="47.5129" r="20.2443" fill="#3366CC"/>
<circle cx="132.319" cy="68.4553" r="20.2443" fill="#3366CC"/>
<circle cx="186.768" cy="68.4553" r="20.2443" fill="#3366CC"/>
<circle cx="142.091" cy="99.8688" r="20.2443" fill="#3366CC"/>
<circle cx="176.298" cy="99.8688" r="20.2443" fill="#3366CC"/>
<g filter="url(#filter2_d)">
<path d="M182.354 86.979C175.301 99.1953 162.837 106.294 142.69 104.383L147.199 96.4283C134.897 89.3257 130.691 73.5796 137.805 61.2583C144.919 48.9371 160.658 44.7065 172.96 51.809C185.262 58.9116 189.468 74.6577 182.354 86.979Z" fill="white"/>
</g>
<line x1="146.85" y1="64.7256" x2="154.892" y2="64.7256" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="159.63" y1="64.7256" x2="173.149" y2="64.7256" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="146.85" y1="71.1157" x2="162.194" y2="71.1157" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="166.933" y1="71.1157" x2="173.149" y2="71.1157" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="146.85" y1="77.5059" x2="151.24" y2="77.5059" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="155.979" y1="77.5059" x2="173.149" y2="77.5059" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="146.85" y1="82.9829" x2="157.18" y2="82.9829" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="161.456" y1="82.9829" x2="164.933" y2="82.9829" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
<line x1="168.759" y1="82.9829" x2="173.149" y2="82.9829" stroke="#2A4B8D" stroke-width="2" stroke-linecap="round"/>
</g>
<g opacity="0.6">
<path d="M51.613 24.2081C46.9629 27.7955 37.9996 37.435 45.9559 39.7651C53.9122 42.0953 56.2092 30.9259 51.613 24.2081Z" fill="#C8CCD1"/>
<path d="M49.7538 22.3489C46.1664 26.999 36.5269 35.9623 34.1968 28.006C31.8666 20.0497 43.036 17.7527 49.7538 22.3489Z" fill="#C8CCD1"/>
<ellipse cx="44.5417" cy="29.1585" rx="10" ry="6.5" transform="rotate(135 44.5417 29.1585)" fill="#FFCC33"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.6318 35.0769C48.149 34.6803 48.6536 34.239 49.1379 33.7547C49.6222 33.2703 50.0635 32.7657 50.4602 32.2485L41.4517 23.24C40.9344 23.6367 40.4298 24.078 39.9455 24.5623C39.4612 25.0466 39.0199 25.5512 38.6233 26.0684L47.6318 35.0769ZM36.6218 29.7238C35.7428 32.2798 35.9669 34.7258 37.4707 36.2295C38.9744 37.7332 41.4204 37.9574 43.9764 37.0784L36.6218 29.7238ZM51.6128 22.0874C53.1165 23.5911 53.3406 26.0371 52.4617 28.5931L45.1071 21.2385C47.6631 20.3596 50.1091 20.5837 51.6128 22.0874Z" fill="black"/>
</g>
<g opacity="0.6">
<path d="M273.209 192.349C276.796 196.999 286.436 205.962 288.766 198.006C291.096 190.05 279.926 187.753 273.209 192.349Z" fill="#C8CCD1"/>
<path d="M271.349 194.208C275.999 197.795 284.963 207.435 277.007 209.765C269.05 212.095 266.753 200.926 271.349 194.208Z" fill="#C8CCD1"/>
<ellipse cx="278.159" cy="199.42" rx="10" ry="6.5" transform="rotate(45 278.159 199.42)" fill="#FFCC33"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M284.077 196.33C283.681 195.813 283.239 195.308 282.755 194.824C282.271 194.34 281.766 193.898 281.249 193.502L272.24 202.51C272.637 203.027 273.078 203.532 273.563 204.016C274.047 204.501 274.552 204.942 275.069 205.339L284.077 196.33ZM278.724 207.34C281.28 208.219 283.726 207.995 285.23 206.491C286.734 204.988 286.958 202.542 286.079 199.986L278.724 207.34ZM271.088 192.349C272.592 190.845 275.038 190.621 277.594 191.5L270.239 198.855C269.36 196.299 269.584 193.853 271.088 192.349Z" fill="black"/>
</g>
<defs>
<filter id="filter0_d" x="185.839" y="102.823" width="48.3897" height="50.3009" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="79.6748" y="90.8057" width="47.4694" height="51.53" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter2_d" x="118.353" y="38.9487" width="78.882" height="82.2582" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -270,17 +270,19 @@ class HookUtils {
return (
// ?title=...&action=edit&section=new
// ?title=...&action=edit&redlink=1
// ?title=...&veaction=editsource&section=new
( $req->getVal( 'action' ) === 'edit' || $req->getVal( 'veaction' ) === 'editsource' ) &&
$req->getVal( 'section' ) === 'new' &&
( $req->getVal( 'section' ) === 'new' || (
// a redlink for an existing page will get redirected to the regular view, so we don't want
// to let our empty state take it over
$req->getVal( 'redlink' ) === '1' && !$context->getTitle()->exists()
) ) &&
// Adding a new topic with preloaded text is not supported yet (T269310)
!(
$req->getVal( 'editintro' ) || $req->getVal( 'preload' ) ||
$req->getVal( 'preloadparams' ) || $req->getVal( 'preloadtitle' )
) &&
// TODO If the page doesn't exist yet, we'll need to handle the interface differently,
// for now just don't enable the tool there
$context->getTitle()->exists() &&
// User has new topic tool enabled (and not using &dtenable=0)
self::isFeatureEnabledForOutput( $out, self::NEWTOPICTOOL )
);

View file

@ -9,6 +9,7 @@
namespace MediaWiki\Extension\DiscussionTools\Hooks;
use Article;
use Html;
use IContextSource;
use MediaWiki\Actions\Hook\GetActionNameHook;
@ -17,11 +18,15 @@ use MediaWiki\Extension\DiscussionTools\SubscriptionStore;
use MediaWiki\Hook\BeforePageDisplayHook;
use MediaWiki\Hook\OutputPageBeforeHTMLHook;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\Hook\BeforeDisplayNoArticleTextHook;
use OOUI\ButtonWidget;
use OutputPage;
use RequestContext;
use Skin;
use VisualEditorHooks;
class PageHooks implements
BeforeDisplayNoArticleTextHook,
BeforePageDisplayHook,
GetActionNameHook,
OutputPageBeforeHTMLHook
@ -47,6 +52,7 @@ class PageHooks implements
*/
public function onBeforePageDisplay( $output, $skin ): void {
$user = $output->getUser();
$req = $output->getRequest();
// Load style modules if the tools can be available for the title
// as this means the DOM may have been modified in the parser cache.
if ( HookUtils::isAvailableForTitle( $output->getTitle() ) ) {
@ -68,7 +74,6 @@ class PageHooks implements
$services = MediaWikiServices::getInstance();
$optionsLookup = $services->getUserOptionsLookup();
$req = $output->getRequest();
$editor = $optionsLookup->getOption( $user, 'discussiontools-editmode' );
// User has no preferred editor yet
// If the user has a preferred editor, this will be evaluated in the client
@ -96,7 +101,12 @@ class PageHooks implements
}
// Replace the action=edit&section=new form with the new topic tool.
if ( HookUtils::shouldUseNewTopicTool( $output->getContext() ) ) {
if (
HookUtils::shouldUseNewTopicTool( $output->getContext() ) &&
// unless we got here via a redlink, in which case we want to allow the empty
// state to be displayed:
$req->getVal( 'redlink' ) !== '1'
) {
$output->addJsConfigVars( 'wgDiscussionToolsStartNewTopicTool', true );
// For no-JS compatibility, redirect to the old new section editor if JS is unavailable.
@ -145,12 +155,7 @@ class PageHooks implements
}
}
foreach ( HookUtils::FEATURES as $feature ) {
// Add a CSS class for each enabled feature
if ( HookUtils::isFeatureEnabledForOutput( $output, $feature ) ) {
$output->addBodyClasses( "ext-discussiontools-$feature-enabled" );
}
}
$this->addFeatureBodyClasses( $output );
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) {
$text = CommentFormatter::postprocessTopicSubscription(
@ -178,4 +183,98 @@ class PageHooks implements
$action = 'view';
}
}
/**
* BeforeDisplayNoArticleText hook handler
* @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforeDisplayNoArticleText
*
* @param Article $article The (empty) article
* @return bool|void This hook can abort
*/
public function onBeforeDisplayNoArticleText( $article ) {
// We want to override the empty state for articles on which we would be enabled
$title = $article->getTitle();
$oldid = $article->getOldID();
if ( $oldid || $title->hasSourceText() ) {
// The default display will probably be useful here, so leave it.
return true;
}
$context = $article->getContext();
$output = $context->getOutput();
if ( !HookUtils::isFeatureEnabledForOutput( $output, HookUtils::NEWTOPICTOOL ) ) {
// Our empty states are all about using the new topic tool
return true;
}
$output->enableOOUI();
$output->enableClientCache( false );
// OutputPageBeforeHTML won't have run, since there's no parsed text
// to display, but we need these classes or reply links won't show
// after a topic is posted.
$this->addFeatureBodyClasses( $output );
$coreConfig = RequestContext::getMain()->getConfig();
$iconpath = $coreConfig->get( 'ExtensionAssetsPath' ) . '/DiscussionTools/images';
$dir = $context->getLanguage()->getDir();
$lang = $context->getLanguage()->getHtmlCode();
$output->addHTML(
// This being mw-parser-output is a lie, but makes the reply controller cope much better with everything
Html::openElement( 'div', [ 'class' => "ext-discussiontools-emptystate mw-parser-output noarticletext" ] ) .
Html::openElement( 'div', [ 'class' => "ext-discussiontools-emptystate-text" ] )
);
if ( $title->equals( $output->getUser()->getTalkPage() ) ) {
$output->addHTML(
Html::rawElement( 'h3', [], $context->msg( 'discussiontools-emptystate-title-self' )->parse() ) .
Html::rawElement( 'p', [], $context->msg( 'discussiontools-emptystate-desc-self' )->parse() )
);
} else {
$titleMsg = $title->getNamespace() == NS_USER_TALK ?
'discussiontools-emptystate-title-user' :
'discussiontools-emptystate-title';
$output->addHTML(
Html::rawElement( 'h3', [], $context->msg( $titleMsg )->parse() ) .
Html::rawElement( 'p', [],
$context->msg(
$title->getNamespace() == NS_USER_TALK ?
'discussiontools-emptystate-desc-user' :
'discussiontools-emptystate-desc'
)->parse()
) .
new ButtonWidget( [
'label' => $context->msg( 'discussiontools-emptystate-button' )->text(),
'href' => $title->getLocalURL( 'action=edit&section=new' ),
'flags' => [ 'primary', 'progressive' ]
] )
);
}
$output->addHTML(
Html::closeElement( 'div' ) .
Html::element( 'img', [
'src' => $iconpath . '/emptystate.svg',
'class' => "ext-discussiontools-emptystate-logo",
// This is a purely decorative element
'alt' => "",
] ) .
Html::closeElement( 'div' )
);
return false;
}
/**
* Helper to add feature-toggle classes to the output's body
*
* @param OutputPage $output
* @return void
*/
protected function addFeatureBodyClasses( OutputPage $output ): void {
foreach ( HookUtils::FEATURES as $feature ) {
// Add a CSS class for each enabled feature
if ( HookUtils::isFeatureEnabledForOutput( $output, $feature ) ) {
$output->addBodyClasses( "ext-discussiontools-$feature-enabled" );
}
}
}
}

View file

@ -46,6 +46,18 @@ OO.inheritClass( NewTopicController, CommentController );
NewTopicController.static.initType = 'section';
NewTopicController.static.suppressedEditNotices = [
// Ignored because we have a custom warning for non-logged-in users.
'anoneditwarning',
// Ignored because it contains mostly instructions for signing comments using tildes.
// (Does not appear in VE notices right now, but just in case.)
'talkpagetext',
// Ignored because the empty state takeover has already explained
// that this is a new article.
'newarticletext',
'newarticletextanon'
];
/* Methods */
/**
@ -71,13 +83,7 @@ NewTopicController.prototype.setupReplyWidget = function ( replyWidget, data ) {
this.$notices.empty();
for ( var noticeName in this.replyWidget.commentDetails.notices ) {
if (
// Ignored because we have a custom warning for non-logged-in users.
noticeName === 'anoneditwarning' ||
// Ignored because it contains mostly instructions for signing comments using tildes.
// (Does not appear in VE notices right now, but just in case.)
noticeName === 'talkpagetext'
) {
if ( this.constructor.static.suppressedEditNotices.indexOf( noticeName ) !== -1 ) {
continue;
}
var noticeItem = this.replyWidget.commentDetails.notices[ noticeName ];

View file

@ -22,10 +22,7 @@ function ReplyLinksController( $pageContainer ) {
if ( featuresEnabled.newtopictool && mw.user.options.get( 'discussiontools-newtopictool' ) ) {
// eslint-disable-next-line no-jquery/no-global-selector
var $addSectionTab = $( '#ca-addsection' );
// TODO If the page doesn't exist yet, we'll need to handle the interface differently,
// for now just don't enable the tool there
var pageExists = !!mw.config.get( 'wgRelevantArticleId' );
if ( $addSectionTab.length && pageExists ) {
if ( $addSectionTab.length ) {
this.$addSectionLink = $addSectionTab.find( 'a' );
this.$addSectionLink.on( 'click keypress', this.onAddSectionLinkClickHandler );

View file

@ -562,6 +562,16 @@ function update( data, comment, pageName, replyWidget ) {
linksController = null;
// TODO: Tell controller to teardown all other open widgets
var pageExists = !!mw.config.get( 'wgRelevantArticleId' );
if ( !pageExists ) {
// The page didn't exist before this update, so reload it. We'd handle
// setting up the content just fine (assuming there's a
// mw-parser-output), but fixing up the UI tabs/behavior is outside
// our scope.
window.location = mw.util.getUrl( pageName, { dtrepliedto: comment.id } );
return;
}
// Update page state
if ( pageName === mw.config.get( 'wgRelevantPageName' ) ) {
// We can use the result from the VisualEditor API

View file

@ -9,6 +9,17 @@ var controller = require( './controller.js' ),
mw.dt = {};
mw.dt.initState = {};
if ( uri.query.dtrepliedto ) {
// If we had to reload the page to highlight the new comment, extract that data from the URL and
// clean it up.
mw.dt.initState.repliedTo = uri.query.dtrepliedto;
if ( window.history.replaceState ) {
delete uri.query.dtrepliedto;
window.history.replaceState( {}, '', uri.toString() );
}
}
mw.dt.init = function ( $container ) {
if ( $container.is( '#mw-content-text' ) || $container.find( '#mw-content-text' ).length ) {
// eslint-disable-next-line no-jquery/no-global-selector

View file

@ -163,3 +163,16 @@ span[ data-mw-comment-start ] {
}
}
}
.ext-discussiontools-emptystate {
display: flex;
justify-content: space-between;
.ext-discussiontools-emptystate-text > p {
margin: 2em 0;
}
}
.ext-discussiontools-init-replylink-open .ext-discussiontools-emptystate {
display: none;
}