From 52c0ec270061546b05ce07dd402c086113d0235b Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 7 Aug 2016 11:33:41 -0700 Subject: [PATCH 01/17] Update Phabricator logo Summary: This updates the eye logo and removes the formal wordmark "Phabricator" as an image. Instead we'll use the new updated eye logo and plain text for "Phabricator", both of which are more friendly and less industrial. Installs that already use the `header-logo` customization setting will need to rebuild their logo to 80px x 80px. They will then also get to use plain text to whitebox their install as they see fit. Test Plan: Tested new logo at desktop, tablet, and mobile sizes. Set a random instance name, saw new wordmark. Created a really long wordmark of MMMMMMMMMMMM, saw text cut off so UI doesn't break. May need some additional tweaking, but I think we covered the most edge cases here. {F1751791, size=full} Reviewers: epriestley Reviewed By: epriestley Subscribers: edibiase, bjshively, yelirekim, Korvin Maniphest Tasks: T4214, T11096 Differential Revision: https://secure.phabricator.com/D16373 --- resources/celerity/map.php | 18 +++--- resources/celerity/packages.php | 1 - resources/sprite/manifest/menu.json | 31 ----------- resources/sprite/menu_1x/dark-eye.png | Bin 2044 -> 0 bytes resources/sprite/menu_1x/dark-logo.png | Bin 1403 -> 0 bytes resources/sprite/menu_1x/light-eye.png | Bin 1794 -> 0 bytes resources/sprite/menu_1x/light-logo.png | Bin 1337 -> 0 bytes resources/sprite/menu_2x/dark-eye.png | Bin 3528 -> 0 bytes resources/sprite/menu_2x/dark-logo.png | Bin 1758 -> 0 bytes resources/sprite/menu_2x/light-eye.png | Bin 2876 -> 0 bytes resources/sprite/menu_2x/light-logo.png | Bin 1699 -> 0 bytes scripts/celerity/generate_sprites.php | 1 - .../celerity/CeleritySpriteGenerator.php | 52 ------------------ .../option/PhabricatorUIConfigOptions.php | 10 +++- .../page/menu/PhabricatorMainMenuView.php | 34 +++++++----- .../css/application/base/main-menu-view.css | 33 ++++++----- webroot/rsrc/css/sprite-menu.css | 36 ------------ webroot/rsrc/image/logo/light-eye.png | Bin 0 -> 1350 bytes webroot/rsrc/image/sprite-menu-X2.png | Bin 4333 -> 0 bytes webroot/rsrc/image/sprite-menu.png | Bin 2173 -> 0 bytes 20 files changed, 56 insertions(+), 160 deletions(-) delete mode 100644 resources/sprite/manifest/menu.json delete mode 100644 resources/sprite/menu_1x/dark-eye.png delete mode 100644 resources/sprite/menu_1x/dark-logo.png delete mode 100644 resources/sprite/menu_1x/light-eye.png delete mode 100644 resources/sprite/menu_1x/light-logo.png delete mode 100644 resources/sprite/menu_2x/dark-eye.png delete mode 100644 resources/sprite/menu_2x/dark-logo.png delete mode 100644 resources/sprite/menu_2x/light-eye.png delete mode 100644 resources/sprite/menu_2x/light-logo.png delete mode 100644 webroot/rsrc/css/sprite-menu.css create mode 100644 webroot/rsrc/image/logo/light-eye.png delete mode 100644 webroot/rsrc/image/sprite-menu-X2.png delete mode 100644 webroot/rsrc/image/sprite-menu.png diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 7d846e4cec..92360d0793 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => '90c46327', + 'core.pkg.css' => 'f12c7d47', 'core.pkg.js' => 'b562c3db', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -32,7 +32,7 @@ return array( 'rsrc/css/aphront/typeahead.css' => 'd4f16145', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '0877ed6e', - 'rsrc/css/application/base/main-menu-view.css' => 'b623169f', + 'rsrc/css/application/base/main-menu-view.css' => 'a79b6e52', 'rsrc/css/application/base/notification-menu.css' => 'f31c0bde', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601', 'rsrc/css/application/base/phui-theme.css' => '027ba77e', @@ -163,7 +163,6 @@ return array( 'rsrc/css/phui/workboards/phui-workcard.css' => '0c62d7c5', 'rsrc/css/phui/workboards/phui-workpanel.css' => '92197373', 'rsrc/css/sprite-login.css' => '60e8560e', - 'rsrc/css/sprite-menu.css' => '9dd65b92', 'rsrc/css/sprite-tokens.css' => '9cdfd599', 'rsrc/css/syntax/syntax-default.css' => '9923583c', 'rsrc/externals/d3/d3.min.js' => 'a11a5ff2', @@ -320,6 +319,7 @@ return array( 'rsrc/image/icon/tango/upload.png' => '7bbb7984', 'rsrc/image/icon/unsubscribe.png' => '25725013', 'rsrc/image/lightblue-header.png' => '5c168b6d', + 'rsrc/image/logo/light-eye.png' => 'fcd66408', 'rsrc/image/main_texture.png' => '29a2c5ad', 'rsrc/image/menu_texture.png' => '5a17580d', 'rsrc/image/people/harding.png' => '45aa614e', @@ -343,8 +343,6 @@ return array( 'rsrc/image/resize.png' => 'fd476de4', 'rsrc/image/sprite-login-X2.png' => 'e3991e37', 'rsrc/image/sprite-login.png' => '03d5af29', - 'rsrc/image/sprite-menu-X2.png' => 'cfd8fca5', - 'rsrc/image/sprite-menu.png' => 'd7a99faa', 'rsrc/image/sprite-tokens-X2.png' => '804a5232', 'rsrc/image/sprite-tokens.png' => 'b41d03da', 'rsrc/image/texture/card-gradient.png' => '815f26e8', @@ -785,7 +783,7 @@ return array( 'phabricator-flag-css' => '5337623f', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => '4a021c10', - 'phabricator-main-menu-view' => 'b623169f', + 'phabricator-main-menu-view' => 'a79b6e52', 'phabricator-nav-view-css' => '09f3d0db', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', @@ -891,7 +889,6 @@ return array( 'releeph-request-typeahead-css' => '667a48ae', 'setup-issue-css' => 'db7e9c40', 'sprite-login-css' => '60e8560e', - 'sprite-menu-css' => '9dd65b92', 'sprite-tokens-css' => '9cdfd599', 'syntax-default-css' => '9923583c', 'syntax-highlighting-css' => '769d3498', @@ -1724,6 +1721,9 @@ return array( 'javelin-stratcom', 'javelin-dom', ), + 'a79b6e52' => array( + 'phui-theme-css', + ), 'a80d0378' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1844,9 +1844,6 @@ return array( 'javelin-dom', 'javelin-util', ), - 'b623169f' => array( - 'phui-theme-css', - ), 'b6993408' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2246,7 +2243,6 @@ return array( 'aphront-tooltip-css', 'phabricator-flag-css', 'phui-info-view-css', - 'sprite-menu-css', 'phabricator-main-menu-view', 'phabricator-notification-css', 'phabricator-notification-menu-css', diff --git a/resources/celerity/packages.php b/resources/celerity/packages.php index 103d395f79..66015f6263 100644 --- a/resources/celerity/packages.php +++ b/resources/celerity/packages.php @@ -104,7 +104,6 @@ return array( 'aphront-tooltip-css', 'phabricator-flag-css', 'phui-info-view-css', - 'sprite-menu-css', 'phabricator-main-menu-view', 'phabricator-notification-css', diff --git a/resources/sprite/manifest/menu.json b/resources/sprite/manifest/menu.json deleted file mode 100644 index 68fe112276..0000000000 --- a/resources/sprite/manifest/menu.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "version": 1, - "sprites": { - "dark-eye": { - "name": "dark-eye", - "rule": ".dark-eye", - "hash": "c8112e52666fa1cb509ebb2cdf3a3df5" - }, - "dark-logo": { - "name": "dark-logo", - "rule": ".dark-logo", - "hash": "e3425da87e8f6737d8db0063d064cd7d" - }, - "light-eye": { - "name": "light-eye", - "rule": ".light-eye", - "hash": "5b6bf7c8c10d4f7414d976f6e79ae2ff" - }, - "light-logo": { - "name": "light-logo", - "rule": ".light-logo", - "hash": "bee37c0a86825ec7ded38936b1ba7b65" - } - }, - "scales": [ - 1, - 2 - ], - "header": "\/**\n * @provides sprite-menu-css\n * @generated\n *\/\n\n.sprite-menu {\n background-image: url(\/rsrc\/image\/sprite-menu.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5),\nonly screen and (min-resolution: 1.5dppx) {\n .sprite-menu {\n background-image: url(\/rsrc\/image\/sprite-menu-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", - "type": "standard" -} diff --git a/resources/sprite/menu_1x/dark-eye.png b/resources/sprite/menu_1x/dark-eye.png deleted file mode 100644 index 2e13cbf2a1735ea5837772063aa8295f4298c04b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2044 zcmaJ?X;f3!7EUYnfz~pq2tFabNM*{12}vZ-kfEf{L<~bg84Sq{1jrl=li0dwAp!M; z$0Wr8d{hv{0VqKhh^{y?E4(sjivb)FK|m-i&>IBXAHLqR?mg%1^?iGPdsyqL{n=lv zTVuBd27|3*`q4Ph?reNbKZ3s53px?B*(&KF$^eN#sp85(7=AVd=jNxUL2@|M}g5oF&TK(a20?H`DEZL z91G2oQo$IZU$PtwNM;A}lH+(pKH%dG_evx|4n&}m3r`fqixs3qGO*;A1f7j$6aZg> zDC5Y$TTvk_e>hbl2jMs*9>GInw!=M%NDL0|N%VAwW1%|=O+aDM2sDv|^B|$I@Z|@9 zqRIIJ5{JfEjs@MwK#Wo;C81C%l?tiyKuYA%C=8KEM4_=LEEWMF5Q-$RlADMSD;!rm z&_D%GE|e;T5;5H9ksBpRP?7;i>Dv@UQWoo-W3ghnP*BNGiCifPgG8f5B4b`lXoZpk z{wd?VXhmR>6hv`Ag(N}FgZd$GTp>fX`};sfAf$#wlkgHmpjgSIkpakp zrQ#V3oG%4~p>Ov^QcAh&MYoZC^i~hj0IlS3(AH2K|Vt+5y6)#L=wJ71%ZkuVhD6B zord->WL1IwG_Wq^aD<)`$jK_Dw3tirg zKPZM~UJea+Y>B@G3}zC`q)`GB`$r4SGJ}FP-8y-!OrU+1TUN0e_sQd!vVWIU96K^% zSIVi6vn$u-g%*_t)R(dCx)_?$4Srmz#*|c8KUn2a9;)RK50MVz%9!lMU1>Jn$eAWj z4_DJh^R(iWj_{usizg9Jnqo&rM$|9*#C~B<@;4S5*Y&drFEJNgJ07}|H0=gUEdu*s zy4rB6*A1Wb;Y4(I7Jm4`&N-@QFehX!X3xhqwZ1>GH5^%G%xzdU(~vV8nCiSgGRsNq z9*lP5S=3Rot!C6k279fOo%(xyV^rboCn|;}JnC@bcgZab1iF_ab}iZo&aZ=zb) zY_*H`X0$0%FYj7AaUn}ldV%2jLqtV$zaj2Y`sB9;B*yxh!1{)npgVt(HL<;lH-G=( z>kdm*R@mHVY5==~GF=Ibe;^B)T7OGFWB_+xpU#L`+~;yox+-b!@3h6pDe!*(uOD}P zIcj}89`E$}(OuJcq-MOKr}S9wSk*v_x#h6~Pph5cn`IvvTIG6%?DLw0SA@@}_I5tt zb|JM#gSNKywr(&C*JtDJHt~X2?EsoAuL4uHo-Jng+D>C$6}kWXNLPEW{e;f8MmtJ- zP>C^oXX##6C0WxIhrC!Ajo5NnHPbtf%CvEOJ?P6R=-c1MAJW;n^OJtrmY4oAKa(GK zI#Mt5%x_DbahqdY%2s#Ma?`DA(?_fVH_o%V58mk*l?;UFh=pIbPou|)rb~ZMa;{}yr zJ(poue8&E<^|JYmQyBtf7<`;uV86fyr1p8IPPB;3p38E{^xrm%wp?Plv$Wqwo^D%f z!v0|>Z+&f&OG0h-=#xreC<5#S!jF8{VKhx zal@57v#}i+xH0cxHX&14E_IRL`2(JSMiji@#H=d`R&6^p={w`|ELiV)>$B%6 z!gSrIRgAj(qv6?=TM;+X3ceot9bDItlb+R`$~Z}Jn$R|$XmYOJI#0RiYE|ddbEH2< zwVq1OXuWh>?@%*Wayzf)muP-_r6BqUTh2vod= z|L#-|$ebKl0e<%=XAA#Tv$4T0{ARwJ`3F8$)0CG#4tp1>Ru5n|kGBRour~C)?x@>s zwW)5mj4k*6x_kF=O_zhr?8o^I?7$gj~?um#R=#{V&s&ZbrQ?mP4cP@rDb diff --git a/resources/sprite/menu_1x/dark-logo.png b/resources/sprite/menu_1x/dark-logo.png deleted file mode 100644 index be96d3c13cf16794f99cf8c611d33334a1360622..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1403 zcmeAS@N?(olHy`uVBq!ia0vp^2|%pD!3HE5C;ztuQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07??FOLn2Bde0{8v^K(3-T9Ob#X~hD#969RTqa;7NqJ2 zr55Lx79|7YBTX5m85nl>EdnV7y2i>SKe;qFHLt|e#a0O@qL-4HV&&@Q=G0%ot5o-U3d6}R3*d*?M9h_q;kpAao#t!lZDGi&MQ ztZi=vPY6Dcxx4iAx>e6O9_q+6-kQ`Ix5ECs1B0pYrOB#BX>xKE+XOpb@9JxKx#57o z0R{;M81Cu+@$;$aHj807tU+w?FnA6P+fPA((@fBJZ%2%h_aJ&-=E!g?qAV`$$CHa zqg#{}%?`Fc;(D~@P*l5@#oHA}pQ`fx^|80yC&RsHy6`>-p0%QOH diff --git a/resources/sprite/menu_1x/light-eye.png b/resources/sprite/menu_1x/light-eye.png deleted file mode 100644 index 64e37bcac277d204927c2cc286a918a01c1b5817..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1794 zcmaJ?c~BE)6c5N%4wbVa*BTL_7;=yh66FXvfR-R~8L9|5HWDG(kSr4JOQnER#A6Vp zqB1xZ<*0xl76SvKh=5A1(pDiLg{c%Nb}Dk%4TAO$>(1o+$)lJpr=}Hq5+Y>1HF^P z#<8VzFh=B;ECWN514H@Av3!aE?d1tlfng~Xi%m>SbV+n|fn6SAmhpH?Blr zfO5V}B!xwg1W-rh@}LCR1C20!SAtl|X1@m@DCfD_GG7Eaj6}DqRM0VMrDVL2)b7 z3yOhYNFD=80XltYT7V;)%NI%1MkjTHm-&J+(SA_Cl0jl%sY6uJM_4dfG`bJnjmaYU z(2xpjutQnbA?S0z9Qq|;Gq!FG&99lKq{&dxz z9N|knV&-CzkkH!(l&lHNI=gsu(lkcbj@bBY$dF?_n)J|waul334IE2P z0*V*F(h_s@7#-(imL*qi)tS(m$WODaNqRM_cYSu&pwse7X1XVs`bA7-Ut%q8U6xbo zaaN0AyZM~v;CiJ^#?XGdff@OAVfDV@mVrF)k=_MWW?@^W)R$Jk%diE) z&%NAb<~O9(Pw(OtL^lJv19|04i`JAA4JYqK*3A62$&H(RLK#jiYt%EjkaR%1z18A) zHoG(rocX%L%V#d7`EtOB_IfLuGr42J81seS&5g+iCoSiaX~pb$t5-i_w8v^^Fh>lk z+VXm|o{dL!FBV!@33MmtW*2nH-CL}V){LKp^oeWwcAw5_$VWYVTX9h7Tn~l6nHuc5 zx~HP+=1&0|9?Figr-QWhm8hFt(}QutZ?kt|Yv|?cLI;oQKEHADHt*b_@9o_EydqWB z#MYFi{a~!|-OgX9qii~=!xH@Xn+v-zI$is0M|8O4M}w3x&YC$w_Tx^lK0{cC_Zbr4 zyf3DeqHa}$?Urw!AR9i42x!tbd@!{sL($;iY8hwh1vmvc_$NqFxpji#Nt4?uo4W(n zTN5;RlNRaDWuq!0ekcyr5^vl1WK^}<_6BQLWnO~MYoS)iy$UI&#K4nX2WiAdR~0Hf zdc2=>zZUc}&ZbxSv{l=_l96Yb(`&E1wywPAix+Mv?ddy_pP^;2^C~IAtceyj(20(= z+gx&fG-iZqv|IaXXEiy^;fDtk7IodeGi4o$+@{K;YqwRAh5d)~c*8*#?%229PZtp) z+6!GTM?er~b0eNTOWK;2R0}11xAtv%fp)A?zu1s>AZ;z2*;Q^lkn=RiK|ic~?&n8U}fi7AzZCsS=07??FOLn2Bde0{8v^K(3-T9Ob#X~hD#969RTqa;7NqJ2 zr55Lx79|7YBTX5m85nl>EdnV7y2i>SKe;qFHLt|e#a0O@qL-4HV&!6PXkut=?rLCU zWNB#VYHHzPV&H7#Xz6U^V&H0O>Il>8nO9trn3tRi)0>IV>w;IWm2**QVo82cNPd0} zEcOC2@=NlIGx7@*oSnh3rJ&)Pn4Fmh64V3*Fx0)NMVV!(DQ-pixeDMAvdYBb3RgEr zXD4SfM>kU^N1zW(oD9s2+?;_a!Oga2RcR{6un5%4HE*U zArKRuc!3;v@=whJruiaZ;?9(tqzBAi%ROBjLn>~)iSEultRQkEQ0xU)<0~Zi(hho_owvC`^mRl)u`yx%ik7r*5$s_>%CC9Zm(Bw*YP#_S^hE) zU;Iux_EPu$!!1Q%C3>-<3k9wG3u}trCEel|T6iHQ)9$`cwUOc4Lcc3qPrvfj?p11U zkXi4Nue2w+#VzJvVbfp=$Bg-|33e`ds2>vS*t;A!Hp&c zi3@+kOeW2mdN^#3>SXcm2{PL+M8>fBOtTHCuvjGUTpK8sx!m>Lng0(g4}4prkdhd; zdV(Ial~8){G0wKfM(VA~#+4g6P8M>@b~;Oh3NSDi2;XDf^`-hxL{Tf_@5Sn=36t3p zxSJR)n6nmsSR$5=&k>1DN|mK%C~~eyDK>^C1tJryMKq9cJze0AIlB|f&??3!!kU3<)(7*`8`tA0NYz#LX^^6`DJ~{&`%sgHFT-G@y GGywqMwc0fR diff --git a/resources/sprite/menu_2x/dark-eye.png b/resources/sprite/menu_2x/dark-eye.png deleted file mode 100644 index dd28bf3a8cb98aa5ba9b09275f23577c8e1c5668..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3528 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 diff --git a/resources/sprite/menu_2x/dark-logo.png b/resources/sprite/menu_2x/dark-logo.png deleted file mode 100644 index 0920a8a6ec77e85d03a2d0a09800cdcf73d23a57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1758 zcmah~c~BE)6kjD+4iT&;PK(QettiQELKc#h2)U400yI#Kqo`rCK!DB0WFraVMK5uz zhz8qQlNmew2C6s7DTZUN0f0uY7t9Yq1p`+=^xha%)ak^Z{F{{-#d2p zKy36n54UA*004L>B4sM(yuiG%E^`rL*put2US*I64j~ZJbP^T3^ z8&M^qG)RdQU1X+_h|7$Q$1~G#p%w~T3x--SCICs$8qh+f>rI$N1Wm=o7~O7$A#lot zP7^^dNU4>vpp-HaAj%15;|P}zh6p)aG&n>U5(x5`JB$cm9>PY17#f5jJaGDfm~2LE z5~h+xOy^>5A}EEX4Hyh(WMptMf;f~h8RiOwLKxw}JRY0zV4JLZT4Q1BO@59DGQxx# zbp~2T=|Ou$O(JEcMG(XEMG2%qseBn&Z<=lt(=yniF~D370+Xb@t|@O5ts-VXOaw6&j#j6|q^LlK1citrP>F=g zmGcEbh?vo&K@u?%fd~-?R-rf18a+-pu(}zn@U>V>Y9ur?WsIk&bjS2!Qz)7;rBDV? zDxI1ZxKgRXb$Yuoz~10#zJyV?lh8&ODH5FO5T<(t3nWCsN5lfIT!!$cDi8~Tr7~28 z%K2gx36eq6SnVsSpT_e36ALqBVEcIgHExHA*&)07a(S7{%k?Mp%+4E`U;xyn+MMe2amO`DBm3Ee(a8V zf%S*9^xWU-CdsCd0e{w{`1!D}x1TznsGpsEe2ofl0rmm^E08t8gBQEDwH)rLYTHp< zmwIJw|29)2HP%om7|vNb@`2!;4Vm}%D1X^qOODu*ien}$k5^A*);*GRRO1!vI==f+ zaJXljmWDOP+e*w86C=6vFNEH}dqzF8{F~}L&|9aj-D%reS=G3tp=I|#GynU%%hCtC z%F5CjZSx9eH^sM}pOyEdtMzePe{@X>JibXG4J-|fDvUwRCsc6heelSkD zRhUN>m0)VYnv~K{b8?saUOVoe?=;lLeZN#1xX~X!bo`A2g2LOCZ)cy2>*=YprS9?O zyMAN)X{=;LaoNyiE0Dd61+ai{fDzdTJp$BoNAjOXpJmNTgx+_0bbpRYh3s_Adh$yL6xatJJIc;N9Wp$v!7-#F5AAHGxOVn+Ce& zybY25W5WF4zc;#9$wxy@n@8*4E5FUEmhc7>pD7Gm7PcJ4Tyiv*x|h0toXYS-T^yU> zwWQp2>%5WPM^~+%fA|#`9{ASg{Dfxn{s6B4N2OEcvhQX6aj;CpZJC={R1Mt!mbG#| z7|L-E;}=D)N*`U&6@Bh^|AMk{#JQm(7wsypxFWso6iT->(k*?x;C_7!#r7&G4)c*4 zy=$(nI=i{o`HMPq(oitx-uTYG-qij2u1)MAbE}J?^VZM=n^hQI6ddEUM%iacx1RZW z(?CQ0u2}J<@h8_46Hcs1@Hzd-{FyetPTRg`mn#Br+$O=jPZORoKO8_IkCs(Rwtx5! DmM?+j diff --git a/resources/sprite/menu_2x/light-eye.png b/resources/sprite/menu_2x/light-eye.png deleted file mode 100644 index 267ba6c1cb4873ae047ed702acc430f7cd280a22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2876 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 diff --git a/resources/sprite/menu_2x/light-logo.png b/resources/sprite/menu_2x/light-logo.png deleted file mode 100644 index a9710c8857f294fa148a267d1f1a56aa85ff2de8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1699 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($gAGXf@2YYEQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07??FOLn2Bde0{8v^K(3-T9Ob#X~hD#969RTqa;7NqJ2 zr55Lx79|7YBTX5m85nl>EdnV7y2i>SKe;qFHLt|e#a0O@qL-4HVr5|NVs2q>W^7<& zIl>8nO9trn3tRi)0>IVYlK&?m2**QVo82cNPd0} zEcOC2@=NlIGx7@*oSnh3rJ&)Pn4Fmh64V3*Fx0)NMVV!(DQ-pixeDMAvdYBb3TL33 z4UEk#-AtXFfIcv>Fg9=mvYd^b91YwIEDe;PdQ-6Y9;(+7r(S)aWAs7Mixk~3Az&H; zG2w|9$bl#S)I4CCF9Ig+>i^a%z&s=9>EaktaqG?9*M+kkL>v-tK4!bq6dmB@pn62r zLUl*$l9m-L%UMF4t~f;%aJuw->~V6~+>si2usrQs`lTl=E(y6E!mviU{{(XUJY*+jeF+@r@d zt=Dv)$i`)74&Sg?&wNZS>VDE(5C zCshkMJLn4O25i5tZsvb%z<4M6Pk`**!TClo+?X(FuP^} z7YlNz@jSP^9MKWd?R}mxsdk?2Gnu9<8~copc%2lgS1Jk6JtoIE?azm$ewX@rk`i3@8I*T^Y2G}m=dYuvhL^w&yVx#@AKdI>8z%iZ`2d2 z{yO`?O7Alfnw>MxM@wF|-zs6H`A@27ZjGE!wzcz`DQEs3WiRf{lzy#L!P|aDCRs5^ zm!l!n85*$(u``7C$lUt={`GSc_e{kDQ5pZay#G36sO$PQA|m`iZ-K|2JFAXues+7o zQ(o=>U7v<7hL@Z(e@r~wyd*jJPtpUwX|J6(tU2~rHq)$ diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index 61f63d155d..ccdd194b36 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -27,7 +27,6 @@ $webroot = Filesystem::readablePath($webroot); $generator = new CeleritySpriteGenerator(); $sheets = array( - 'menu' => $generator->buildMenuSheet(), 'tokens' => $generator->buildTokenSheet(), 'login' => $generator->buildLoginSheet(), ); diff --git a/src/applications/celerity/CeleritySpriteGenerator.php b/src/applications/celerity/CeleritySpriteGenerator.php index 0dba6c346f..8c09bbc59f 100644 --- a/src/applications/celerity/CeleritySpriteGenerator.php +++ b/src/applications/celerity/CeleritySpriteGenerator.php @@ -2,58 +2,6 @@ final class CeleritySpriteGenerator extends Phobject { - public function buildMenuSheet() { - $sprites = array(); - - $colors = array( - 'dark', - 'light', - ); - - $sources = array(); - foreach ($colors as $color) { - $sources[$color.'-logo'] = array( - 'x' => 96, - 'y' => 40, - 'css' => '.'.$color.'-logo', - ); - $sources[$color.'-eye'] = array( - 'x' => 40, - 'y' => 40, - 'css' => '.'.$color.'-eye', - ); - } - - $scales = array( - '1x' => 1, - '2x' => 2, - ); - - $template = new PhutilSprite(); - foreach ($sources as $name => $spec) { - $sprite = id(clone $template) - ->setName($name) - ->setSourceSize($spec['x'], $spec['y']) - ->setTargetCSS($spec['css']); - - foreach ($scales as $scale_name => $scale) { - $path = 'menu_'.$scale_name.'/'.$name.'.png'; - $path = $this->getPath($path); - - $sprite->setSourceFile($path, $scale); - } - $sprites[] = $sprite; - } - - $sheet = $this->buildSheet('menu', true); - $sheet->setScales($scales); - foreach ($sprites as $sprite) { - $sheet->addSprite($sprite); - } - - return $sheet; - } - public function buildTokenSheet() { $icons = $this->getDirectoryList('tokens_1x'); $scales = array( diff --git a/src/applications/config/option/PhabricatorUIConfigOptions.php b/src/applications/config/option/PhabricatorUIConfigOptions.php index e73b4ee780..00bf33faa0 100644 --- a/src/applications/config/option/PhabricatorUIConfigOptions.php +++ b/src/applications/config/option/PhabricatorUIConfigOptions.php @@ -69,6 +69,14 @@ EOJSON; " omit this if you just want a piece of text, like a copyright ". " notice.")) ->addExample($example, pht('Basic Example')), + $this->newOption('ui.custom-wordmark', 'string', array()) + ->setSummary( + pht( + 'Customize the text next to the logo.')) + ->setDescription( + pht( + "Allows you to change the text (Phabricator by default) ". + "next to the Phabricator logo.\n\n")), $this->newOption( 'ui.custom-header', 'custom:PhabricatorCustomHeaderConfigType', @@ -80,7 +88,7 @@ EOJSON; 'phid for a viewable image you have uploaded to Phabricator '. 'via the [[ /file/ | Files application]]. This image should '. 'be:'."\n". - ' - 192px X 80px; while not enforced, images with these '. + ' - 80px X 80px; while not enforced, images with these '. 'dimensions will look best across devices.'."\n". ' - have view policy public if [[ '. '/config/edit/policy.allow-public | `policy.allow-public`]] '. diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index 25dba1871a..f353012a5a 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -298,7 +298,9 @@ final class PhabricatorMainMenuView extends AphrontView { private function renderPhabricatorLogo() { $style_logo = null; + $logo = null; $custom_header = PhabricatorEnv::getEnvConfig('ui.custom-header'); + $custom_wordmark = PhabricatorEnv::getEnvConfig('ui.custom-wordmark'); if ($custom_header) { $cache = PhabricatorCaches::getImmutableCache(); $cache_key_logo = 'ui.custom-header.logo-phid.v1.'.$custom_header; @@ -315,17 +317,27 @@ final class PhabricatorMainMenuView extends AphrontView { } if ($logo_uri) { $style_logo = - 'background-size: 96px 40px; '. + 'background-size: 40px 40px; '. 'background-position: 0px 0px; '. 'background-image: url('.$logo_uri.');'; } + + $logo = phutil_tag( + 'span', + array( + 'class' => 'phabricator-main-menu-logo', + 'style' => $style_logo, + ), + ''); } - $color = PhabricatorEnv::getEnvConfig('ui.header-color'); - if ($color == 'light') { - $color = 'dark'; - } else { - $color = 'light'; + if (!$logo) { + $logo = phutil_tag( + 'span', + array( + 'class' => 'phabricator-wordmark', + ), + (($custom_wordmark) ? $custom_wordmark : pht('Phabricator'))); } return phutil_tag( @@ -344,16 +356,10 @@ final class PhabricatorMainMenuView extends AphrontView { phutil_tag( 'span', array( - 'class' => 'sprite-menu phabricator-main-menu-eye '.$color.'-eye', - ), - ''), - phutil_tag( - 'span', - array( - 'class' => 'sprite-menu phabricator-main-menu-logo '.$color.'-logo', - 'style' => $style_logo, + 'class' => 'phabricator-main-menu-eye', ), ''), + $logo, )); } diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index 8be3a97f5e..7496e9a060 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -41,27 +41,20 @@ } .phabricator-main-menu-brand { - display: inline-block; - width: 148px; height: 44px; float: left; - margin-right: 4px; + margin-right: 6px; padding-left: 6px; } -.phabricator-main-menu-logo { - position: absolute; - width: 96px; - height: 40px; - left: 52px; - top: 2px; -} - .phabricator-main-menu-eye { - position: absolute; + margin: 2px 0; width: 40px; height: 40px; - top: 2px; + float: left; + display: block; + background-image: url(/rsrc/image/logo/light-eye.png); + background-size: 40px 40px; } .device-desktop .phabricator-main-menu-brand:hover { @@ -69,6 +62,20 @@ cursor: hand; } +.device-phone .phabricator-wordmark { + max-width: 112px; /* iPhone 5 limitation */ +} + +.phabricator-wordmark { + float: left; + color: #fff; + font-size: 18px; + margin: 9px 4px 9px 6px; + padding-right: 8px; + max-width: 175px; + overflow: hidden; +} + /* - Expand/Collapse Button ---------------------------------------------------- On phones, the menu switches to a vertical layout and uses a button to expand diff --git a/webroot/rsrc/css/sprite-menu.css b/webroot/rsrc/css/sprite-menu.css deleted file mode 100644 index 61e1240b07..0000000000 --- a/webroot/rsrc/css/sprite-menu.css +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @provides sprite-menu-css - * @generated - */ - -.sprite-menu { - background-image: url(/rsrc/image/sprite-menu.png); - background-repeat: no-repeat; -} - -@media -only screen and (min-device-pixel-ratio: 1.5), -only screen and (-webkit-min-device-pixel-ratio: 1.5), -only screen and (min-resolution: 1.5dppx) { - .sprite-menu { - background-image: url(/rsrc/image/sprite-menu-X2.png); - background-size: 97px 123px; - } -} - - -.dark-logo { - background-position: 0px 0px; -} - -.dark-eye { - background-position: 0px -82px; -} - -.light-logo { - background-position: 0px -41px; -} - -.light-eye { - background-position: -41px -82px; -} diff --git a/webroot/rsrc/image/logo/light-eye.png b/webroot/rsrc/image/logo/light-eye.png new file mode 100644 index 0000000000000000000000000000000000000000..19d28b72e72c97b3d35380f0f857cf7b7e423650 GIT binary patch literal 1350 zcmV-M1-bf(P)l6RaMcoPYS_8XQ5N*S*S|s z>=O!x(M7FgWik`gRW;$p$0>FQIeS@=%mphEVv20Gu@cl(8?UTK3fikSSlubLm)aFQ zYu)S<3Ra`5>B{8^SdA08g|``m3qX!Ryw0s0%gW{P2dWqmv{UsbWIG-vPdz;DWjlYO zj0BU*1~YIjqe#jy&J3ovxGr{rGQlLAPXSvz&h#hJl=L{|wm*|pkFEHHwEV)xX#_=d zxnO**LdWGhJ{p_v@X)!;AAf*?nk=*MAtv7C9M)y#az~|E?qFut|-%z@s z2n+HPk`bKEJoUyi59crf$xqCaUQp8;Oca+BgNe#*i5{wxaEUUQg%S$-t*P`LXBNF5 zzd@LlClV`4!DQ(1R0{=2Be9ytTInyRb{przoBT$rT+7z2|}sLvK#r z17I+V_kVUY0E0QsG&$(t`M6@dS67gEVtPg9GB!7+!bp}5KiQWG!<6ZBQzXhy%wg_2 zL5pF)9Q=gjJlT?hq2m2KOqGIqea;6}Q3}>Z)$^EA`Kp!CK^2?|Pgm3g!!Wx+4=z`~ zYDIJi+SGklKoUhKksd5vJ;SwOdOoBcmuZSD14$H}M0(%Q8tF~Qw~PqmGA`ccxiII8 zXSt2-zeA2XMTDLbI?c(v6p z$V%ue5*ggilf-e^ldf=m25!Z~vqEqYbXJNBUWd*EVsszR5T(pYk;V;3K4%IsWdd}r ziwk~_MlNhf#fPco2C+UduF#v_FeQh^_i@1z8iT@y2wl{&nOqll^c2P!gU~3Y5fq`8 z)nlu-Q$x^VFKBy-ML39B4vwvVN-e93b&E@E`;dg;sMsUW9a&$KC3ap6E zB4YF&#JP>0{`H0U4M~v=Q@v)YSiGoT!^Bq{%BpO{r4%qRl=c)a>MBg5|EO~!up?=> zP8{ZynE8omg1s&F1Lnid?4l=cgWrsQWI__0lMMOs@9pv7)kPay(rxo#MHv1lLmboNKQqFI@c3 z&N-CsC@Or&A}qvZRN2V5V|I!}8O+>{#9Hxr+KkQ0)A$wPZ9whs%4-|?Z9E&(n_oAv zQ9Rz*o0voRnopUo<`r@g0gteu>5w>1(aS*5XA`B_N{{$tGNrjOzN(jjqQ@%E0AM9t zT`wC&myJ@-+8|p!{X!o>i}jQi4%07g){5{LGg?iUo=2fUdWxdU@r<8n?|2-Ko4uaE z_-|e#IFmW+?wXx5jQ^1{uaiAY%R88OhqG9V=|p!e&f+ahyw40yW1yRh(aG^0AB@d+ z{LWk4#Br=dx6`CalO|1?H2GKa2cvX%vGt^lX#fBK07*qo IM6N<$g6fcq&;S4c literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/sprite-menu-X2.png b/webroot/rsrc/image/sprite-menu-X2.png deleted file mode 100644 index ea92e0e9cfb48db956cfcecc2bf4d8cfdaa4cf32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4333 zcmaJ@2Q-`e`;QPKHnCTb)(9197qxelR7p{nnzgE`W^Lh8Dt6UwYg9$78rKS{cFk5x z)hsnjt)lp+H~(LLJ@=mTd(WFEpXW24_nhbZo}9#)n&{DkxxoMcfZjk~8%g-?Abj?z z$qBV)ytDxT03Mhco9hr-U1OWGvom5P0Ydvfc#@guC$*&1?>uP^NhJazPjC{=L_n;+ zM@Z^F;v^@@Omvc3A|S*D+9}&_JA|N@5K~g2nA%Nd8(ND?}rN1rzUw)T}6p8sa_(z;zAbS2W zkjVc#{yXz~kmx53A=!wJ`?m^to-adq^^bj#Cf5K>P1@RieoRc$(?UX7Su!#&zrFkx z7k7L-crti$cu2>55|T6x8`Sfx*_ zC9Wl=7H02w_3LB1^OdQQ`RzDhd!}+`w|-O-7KluWqQ=<-n4^5qb~UExAl~g;u8k`j zC|=uFucm5N0&dxT39{v$+TP&q^!Z{gYs25^Dr?H$=w`?g%0j8W7y406onnlgbB=S) z&E(^l1ce$UdzGVv6;=Hl<`5}*ox-dkqqBnGCK~emH_=6&Z z#YmTEZr8iqcO#-ID)sft%NH~+XkLa;odE!JWd_FkRTm}8IPbgrM7Cow#wOA6u%!troudHlAe{b@c2i;UjYb3*IR4BZ}y?Vc2OBX z&pR*oBnQ7RdlkUS+qxa$_>jCzuryk-+J=3O5^AGSFJvRY0j>(BYU=S(isr$Xf~E~; z6TnPz8U2Ev!lT8%z9*lQ7t@EtT=Ri8@;>FksMIf}`3;15bmh}qQj0+JO$fF{h$;3A z`GaCqt^kmg1aFA^b=Ts!yvi|e*lYx&Y}(mu>|v#?9X+2X6Ic>~T2^zMSiCij#5ELm zWEot-V+`^TQmhwM8UwTd@IC>e7XhV_Kns}badg18hWayg3=+?c4QFdO_PYu*Z&GPo|$0^g}Yfa2ip0U>ItN+j7uIkv5w=HNmd z-ds3nz)q(zvKc!pf*k-+z6j?k7q!6n>rV2y;F4VlVi)5jZ)3vZ!x25FFE%Q9-jfj; z!sRkSXK^mtUR1oW2r7JGyz6Jz&of+OpacFzr)SFO0r;wZ29?(ZmuId<$1WKd8Y%{T z7pQUV7$iC;##<}-^@*}$9dI!)4!lBljm1Z%gI?dXu#9c)lnFBWgXWPzPaL%ZR0I8& zMKq7NdRlbOpW^aN;^wcM^}83Lq62^QHe$w1?~M2NG zRCtiMHwZ5$Csv+BX2u9A2PiU1g4e@KQ-R6|Sl;7k0ib+5SQAuQ1xd5`6w)NZBK~Qu zWfojPxVOSCp9Ojyu@a7$aK42n1$`EHV*!xzn_ugiIG5ldLOt0m$N+_=2R)~=Eb5ydtLUdm0zqgr%t!R;vFp&xP`cqj-WbU%WkP|%2OnR<=+B|)jq~>jzvX4@Jz_?VT$J&!aGgg`trx2ppC%OhOAuwrI3SZw1@om@yy%JP_<*{rGtTs zJ6HGjJoXv=tS{DuiAUZK4ag2lnVL^_KyEd0PKw8$yqsZ`LL53F=ihggPcm$L&0O$P(K7Ts=qwezTIZ7VBm46Q`g&bjs&~#wVOKN@ z`0r@&({zQbcG=y$oFpHa@5R`^g`JYjqovHz7XLVZ0XUS;Xk4SL}X z6gVLbL#j1EJZC|br znlm2JU-|=K^adJ%+K}q;5`kLF#{&8~Va^Poj>q}o(ose8g$>C)LMfC9vHNNxono9? z+JfqeBMyjSjQJ=>d-hwTJ^cqa>3g_c6xXK97rOgVp4W^rtQL;ylFiNe>NthC(^*A2 zPttMyBg2i6|z z_vw1ORWV(jJ`A#4+SojuFYD0}a6L4W7>^2*hQU1UwYKI2XE(J4m@VD{)Hb`a$S@^X zNI-1SepZ_vRqGjPuLrIb%B>D|u>2T9M?d8#R2A{BQ}i)1hCTf<430@gNPZA0y~tfx z=kc1IpT_9c!oF^$-20)~0~&6+7_1oAT^*MW*4_pzpsr$-E7D3QWVYxWTtQWp7LP_7 zp=hEqCvNB;w8c~6jTn($t+fFB$n`OOn%GPQgC32K(SJD{E{pfrw2!jNt+%^Nu;~?y zOgy{kRKVSgZg4ov?CZICb=2YAMmrpquKjejyS+ljl+9^dwrTYX%>`Te%%Y&yh&fzF z$ZHq->|V`_iZ_KUTU2z<)%au5=6E=d{Pz2Ond{PFwHmVwRS0SZqmL;S4(>&Z{B^!D zT3Qxd3j3)DvL_W8Z$U`AqD9+k-)JrQ7YS6Z8{{%iy{%pwqApWQ$$1EbHQ#OJW6B?5 zyd@|wxf<)FJ+})Ln_CcU&YTvSbDU7Q1Xat=SJ&hR)@Ef1D3X=XemhMrI%F!YmLVSw zo{l)5Ju7RKXG(je&`M96Q6Oq;gyU3w)RDU1APe}lWi!ifYEBlFXZjG#gn29RlP*&M z<;rN!;-0U`+0&uXpbb;9xT(hy8rgpdRvTU!Q9C3^Cuq-TBg9I6!ASK)VUYg5wjM_{ zdmD}VP4?FCsoU&+n%tXhx8J^J=CjeZ>hJ^X83fRK4JCVni>5f1O0>QPUd1j*G?#^D zOKaku$G(wYVeFKxcqI(TVLTWUq-#@Hg3LI|k+us!VHxKwi9lwJPpGX* zB=E|&L7WY=q7IohJ)@pegfL1&s>l0HbBLxKN#w`(YBngu?6n5*_l~=a+o{N zXxb_`_jG1wh#~-OPZeF(Ivt%iz(+m6+(@qwnK^K-oP*Lgc2ezziD8OJf6XlR(I@_i z4j)~wPS94$rNn`bVLrEqvPxocc@k3L^^`urHi`HL=QI0kEIHHOU{-ad?;$(yF)3&J z%U+aIEev5<-r-0PEP_8j8qrRB9KxxoxAVxk*jW)MXQ214bXgH@l)kBmExw&uqsVn} zdTN1^@49g3U5gB_#vLWOE19`ny{H@SFBKIPgQ`2Z>N;Q_EQI6G4DOGQn}YY;wr(4j z1jJr^&|*-D4HBZsWoJ#id$4+)S+qtaqeFh4UZqdXU&6n;W|x|uFMFNy{=uqq;3ul7 z27g5IgH6Ib+d%S9K4}Lw7xg+#l?_9e5i0<|(b|u{zZX)+Z0f&C7RGhg7-aE(8}VK{5tP>%_}U?vSr+ zGuvt``TlS+45gN69JzAcJXejvhefC*(pZT)e&uTr4vjo_LsfGlV80Z*dacb|w6_IS zhF(MPO;^4%6)$vb5)RKKkE(5Q`FJEbiTYiEUWScwxXs!CE04iu+ z+)F}-ZFKKWR#2*XJ@EK?^psLX|Mynml`0N1lfw18SeCT$iF)9f^U@h0e^8Ok$=!P2 z6+Mc^bhEX1Q*KmCtFl8y_mpGbJ9+_xYNpVXwP&=p?PA0vCeL5L zGSUF8D%=CPZ{v1Xc$Jrvt)^FDRqXGSSe-70ehC_7`7AIj?bv@JJ;(z~VV{=fVDmi1 z8La>D6R&j46y4hfO9`XVs>|vAR@j%boAd$OS#y6v2$f#H*lg^Tn^)F$bha^$r4L5{ zK=vM4&*QnE@7OR*u*=rw$fAsN!yRF0894h;a5%}v**AXDyeIPgomgx1XGte>7uF$lL{6E&4hQR;; diff --git a/webroot/rsrc/image/sprite-menu.png b/webroot/rsrc/image/sprite-menu.png deleted file mode 100644 index bdb250c3c1953d8ddc93d353f37f1f5a9294dbf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2173 zcmZ9Oc{Cf?9>*ghL}?gH)lw}c+S-CrK`liw6}zJ8XoQk3D2lX}5QbPgv|gs0RVuw zy`8lyUw!!_S_I6G{^wVG000qdduvN~+{AKmh<|RZ97A6}zr!fUUoYQ2N7YtmA)BFQ zzoml6ae&$C~IKa5xV!^YFq>;v?ov(*qeY8`oMzpHiF@eTGlttG4MBidu(`zwoe z+^N9gw$7LuUffvhe%&VyX`LHhvOF&T;N{1#)=S!ac{MR<4i|kW_k>LLo2yH2oynot zo>=zs4r^kx_-#<+7dg*%P%!M1WJp_(;ms1)g2tu~{&zzdUNEn*%7Ga@-}~C>bplBx&p812D-n?EOdLeHbWU}v|z912icA}D5RWu4h4#Keg z=G>*nZ!Dy6bI;}rrjoqFNpHRwl5(f40v1c~TZh&adDeY6DpbogGW7Ip1} zx3%Gw!5Kc4sU+%K5Q5PTsYVn2^=*#>7($2okaAJt z@Qq9v8_aJ`Mz$G#|4P_D=jb0+;yYFoL1-Nc zU?tH;0%DdRj0SEbW_hrAONI@HE&;Y_D!+0-N8%yFP~(C}>`9t58>~VXZUDSvY-lBF zpaTWds7ekAAr^~*UVznvw|W#{x@jGZQTq12)L4ja-`?t;PYR-I)?N;kN|6`IF?_u~)eHdC^(6(qoyM)xH)`+{?2a;Ep>%vty!u?-HTA+bZJ3 zF8F-fpBxn&Om|C|&0W~jGnp<2}<5xBNac8IeJeGvuv_JkZ z#g%eOU{lwf@jl^TE9+@{i8M2bw+Z-DhhJG&$R$QMW8)JT(k$8_`rj ztxdyO;{%`jjCF`Y>_=E?g=p;gje(~@kPW$QDxEc{D?}Ltnl=p{zzD>hn5Y-1LOl#2 z1)V1|DEnHy@9HWA1Tlx686FGPXF<$#_fAc6cRCj2xG8Mjq2U8d2GS)!ec z&N98f3@VYs7cBFRIx<-1J*(7spWz_6wW2kqZds4OwP9j=RhntvR=R*x01I#Td`7o- ze2DV#Vxf_RxIDcTQVt%ElkB;g%u8|SD)|-hGEj97ATo_Ft|Ez(bk9xCUT7l^+m$5w zTsuZsl|0lJ=;Kqr#W_GWC^c$lKiTVNA8S??3YB+R?2dv1Ibu=^A2&DkFz0x*R&tN! zQYkjNTny(@IML&HO_$yglKjQ%_9#InACZ>GvKrYEvFmt@48o|>6>Fmu)*rV}VAg28 z;TZuH8|s~;Q1Oh^=FSq9QnBwoW7s6;dUqO3kf&r(efdl`1>9?mnsHjn8f@5C#SXkk z630A2$PimW+HWhwnsg-EQHr~yMEjfGA?AJ+&qzt0@4>pGMWQ{I=H%hfYZHfv(^?1P zhG=R|ea5zD9&LWOjn=rB0`DD2u!9c>QK0wznrosq&j15c@oo;nHj5Iy6vR=3zcZzZ zo8Cagf(Gxwg?cdOV~UXru)atBixaa0W^QV|$nXZCz<)v6Aytd16{9GPu{WDd@ z)R*ZQuc)9Y+j>&e_~3*G(|b$C`?E+!W1l32JcnW_XRDLfJ;VL8tH~9i!*!U!rusfY zJvPI}XGBP5rhBh|1o%L?^9tX&t)EVD*=Sk6uAV0}z1wMZMp1E2S~fcz!E+ije@axa z!JAMc3Esm4t0r$=(2hC!8dNEIjuEvq8}@405?JUGZlX&7UgpFk=e-DIqP);m2<_hG z1SKa0BS64L>fxh|8RwYDTL!+8aZLIhL From 3a002b6b83d6f5f91c53986b31b810fd51be64f6 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 7 Aug 2016 11:39:21 -0700 Subject: [PATCH 02/17] Make new logo and wordmark more reasonably configurable by human users Summary: Fixes T11437. Provides a normal form for configuring this, instead of weird "look up the PHID and adjust things in the database" stuff. Test Plan: {F1753651} {F1753652} Reviewers: chad Reviewed By: chad Maniphest Tasks: T11437 Differential Revision: https://secure.phabricator.com/D16377 --- src/__phutil_library_map__.php | 4 +- .../PhabricatorExtraConfigSetupCheck.php | 4 + .../PhabricatorConfigEditController.php | 47 +++---- .../custom/PhabricatorConfigOptionType.php | 10 ++ .../PhabricatorCustomHeaderConfigType.php | 48 ------- .../PhabricatorCustomLogoConfigType.php | 118 ++++++++++++++++++ .../option/PhabricatorUIConfigOptions.php | 49 ++------ .../page/menu/PhabricatorMainMenuView.php | 60 +++++---- 8 files changed, 200 insertions(+), 140 deletions(-) delete mode 100644 src/applications/config/custom/PhabricatorCustomHeaderConfigType.php create mode 100644 src/applications/config/custom/PhabricatorCustomLogoConfigType.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c5059723a5..04c4198008 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2268,7 +2268,7 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStorage.php', 'PhabricatorCustomFieldStorageQuery' => 'infrastructure/customfield/query/PhabricatorCustomFieldStorageQuery.php', 'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php', - 'PhabricatorCustomHeaderConfigType' => 'applications/config/custom/PhabricatorCustomHeaderConfigType.php', + 'PhabricatorCustomLogoConfigType' => 'applications/config/custom/PhabricatorCustomLogoConfigType.php', 'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php', 'PhabricatorDaemonBulkJobController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobController.php', 'PhabricatorDaemonBulkJobListController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobListController.php', @@ -7014,7 +7014,7 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldStorage' => 'PhabricatorLiskDAO', 'PhabricatorCustomFieldStorageQuery' => 'Phobject', 'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage', - 'PhabricatorCustomHeaderConfigType' => 'PhabricatorConfigOptionType', + 'PhabricatorCustomLogoConfigType' => 'PhabricatorConfigOptionType', 'PhabricatorDaemon' => 'PhutilDaemon', 'PhabricatorDaemonBulkJobController' => 'PhabricatorDaemonController', 'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonBulkJobController', diff --git a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php index 1e2eaa5680..6547f9ca96 100644 --- a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php +++ b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php @@ -328,6 +328,10 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck { 'metamta.re-prefix' => $global_settings_reason, 'metamta.vary-subjects' => $global_settings_reason, + + 'ui.custom-header' => pht( + 'This option has been replaced with `ui.logo`, which provides more '. + 'flexible configuration options.'), ); return $ancient_config; diff --git a/src/applications/config/controller/PhabricatorConfigEditController.php b/src/applications/config/controller/PhabricatorConfigEditController.php index ab246b56ce..71b4499591 100644 --- a/src/applications/config/controller/PhabricatorConfigEditController.php +++ b/src/applications/config/controller/PhabricatorConfigEditController.php @@ -98,7 +98,8 @@ final class PhabricatorConfigEditController } } - $form = new AphrontFormView(); + $form = id(new AphrontFormView()) + ->setEncType('multipart/form-data'); $error_view = null; if ($errors) { @@ -144,9 +145,9 @@ final class PhabricatorConfigEditController } if ($option->getHidden() || $option->getLocked()) { - $control = null; + $controls = array(); } else { - $control = $this->renderControl( + $controls = $this->renderControls( $option, $display_value, $e_value); @@ -201,9 +202,9 @@ final class PhabricatorConfigEditController } } - $form - ->appendChild($control); - + foreach ($controls as $control) { + $form->appendControl($control); + } if (!$option->getLocked()) { $form->appendChild( @@ -279,23 +280,23 @@ final class PhabricatorConfigEditController $e_value = null; $errors = array(); - $value = $request->getStr('value'); - if (!strlen($value)) { - $value = null; - - $xaction->setNewValue( - array( - 'deleted' => true, - 'value' => null, - )); - - return array($e_value, $errors, $value, $xaction); - } - if ($option->isCustomType()) { $info = $option->getCustomObject()->readRequest($option, $request); list($e_value, $errors, $set_value, $value) = $info; } else { + $value = $request->getStr('value'); + if (!strlen($value)) { + $value = null; + + $xaction->setNewValue( + array( + 'deleted' => true, + 'value' => null, + )); + + return array($e_value, $errors, $value, $xaction); + } + $type = $option->getType(); $set_value = null; @@ -415,13 +416,13 @@ final class PhabricatorConfigEditController } } - private function renderControl( + private function renderControls( PhabricatorConfigOption $option, $display_value, $e_value) { if ($option->isCustomType()) { - $control = $option->getCustomObject()->renderControl( + $controls = $option->getCustomObject()->renderControls( $option, $display_value, $e_value); @@ -487,9 +488,11 @@ final class PhabricatorConfigEditController ->setError($e_value) ->setValue($display_value) ->setName('value'); + + $controls = array($control); } - return $control; + return $controls; } private function renderExamples(PhabricatorConfigOption $option) { diff --git a/src/applications/config/custom/PhabricatorConfigOptionType.php b/src/applications/config/custom/PhabricatorConfigOptionType.php index 733229e652..429b080cda 100644 --- a/src/applications/config/custom/PhabricatorConfigOptionType.php +++ b/src/applications/config/custom/PhabricatorConfigOptionType.php @@ -31,6 +31,16 @@ abstract class PhabricatorConfigOptionType extends Phobject { } + public function renderControls( + PhabricatorConfigOption $option, + $display_value, + $e_value) { + + $control = $this->renderControl($option, $display_value, $e_value); + + return array($control); + } + public function renderControl( PhabricatorConfigOption $option, $display_value, diff --git a/src/applications/config/custom/PhabricatorCustomHeaderConfigType.php b/src/applications/config/custom/PhabricatorCustomHeaderConfigType.php deleted file mode 100644 index fee8ba5a4c..0000000000 --- a/src/applications/config/custom/PhabricatorCustomHeaderConfigType.php +++ /dev/null @@ -1,48 +0,0 @@ -setViewer(PhabricatorUser::getOmnipotentUser()) - ->withPHIDs(array($value)) - ->executeOne(); - if (!$file) { - throw new Exception( - pht( - '%s is not a valid file PHID.', - $value)); - } - - $most_open_policy = PhabricatorPolicies::getMostOpenPolicy(); - if ($file->getViewPolicy() != $most_open_policy) { - throw new Exception( - pht( - 'Specified file %s has policy "%s" but should have policy "%s".', - $value, - $file->getViewPolicy(), - $most_open_policy)); - } - - if (!$file->isViewableImage()) { - throw new Exception( - pht( - 'Specified file %s is not a viewable image.', - $value)); - } - } - - public static function getExampleConfig() { - $config = 'PHID-FILE-abcd1234abcd1234abcd'; - return $config; - } - -} diff --git a/src/applications/config/custom/PhabricatorCustomLogoConfigType.php b/src/applications/config/custom/PhabricatorCustomLogoConfigType.php new file mode 100644 index 0000000000..ff29050602 --- /dev/null +++ b/src/applications/config/custom/PhabricatorCustomLogoConfigType.php @@ -0,0 +1,118 @@ + 'optional string|null', + 'wordmarkText' => 'optional string|null', + )); + } + + public function readRequest( + PhabricatorConfigOption $option, + AphrontRequest $request) { + + $viewer = $request->getViewer(); + $view_policy = PhabricatorPolicies::POLICY_PUBLIC; + + if ($request->getBool('removeLogo')) { + $logo_image_phid = null; + } else if ($request->getFileExists('logoImage')) { + $logo_image = PhabricatorFile::newFromPHPUpload( + idx($_FILES, 'logoImage'), + array( + 'name' => 'logo', + 'authorPHID' => $viewer->getPHID(), + 'viewPolicy' => $view_policy, + 'canCDN' => true, + 'isExplicitUpload' => true, + )); + $logo_image_phid = $logo_image->getPHID(); + } else { + $logo_image_phid = self::getLogoImagePHID(); + } + + $wordmark_text = $request->getStr('wordmarkText'); + + $value = array( + 'logoImagePHID' => $logo_image_phid, + 'wordmarkText' => $wordmark_text, + ); + + $errors = array(); + $e_value = null; + + try { + $this->validateOption($option, $value); + } catch (Exception $ex) { + $e_value = pht('Invalid'); + $errors[] = $ex->getMessage(); + $value = array(); + } + + return array($e_value, $errors, $value, phutil_json_encode($value)); + } + + public function renderControls( + PhabricatorConfigOption $option, + $display_value, + $e_value) { + + try { + $value = phutil_json_decode($display_value); + } catch (Exception $ex) { + $value = array(); + } + + $logo_image_phid = idx($value, 'logoImagePHID'); + $wordmark_text = idx($value, 'wordmarkText'); + + $controls = array(); + + // TODO: This should be a PHUIFormFileControl, but that currently only + // works in "workflow" forms. It isn't trivial to convert this form into + // a workflow form, nor is it trivial to make the newer control work + // in non-workflow forms. + $controls[] = id(new AphrontFormFileControl()) + ->setName('logoImage') + ->setLabel(pht('Logo Image')); + + if ($logo_image_phid) { + $controls[] = id(new AphrontFormCheckboxControl()) + ->addCheckbox( + 'removeLogo', + 1, + pht('Remove Custom Logo')); + } + + $controls[] = id(new AphrontFormTextControl()) + ->setName('wordmarkText') + ->setLabel(pht('Wordmark')) + ->setPlaceholder(pht('Phabricator')) + ->setValue($wordmark_text); + + return $controls; + } + + +} diff --git a/src/applications/config/option/PhabricatorUIConfigOptions.php b/src/applications/config/option/PhabricatorUIConfigOptions.php index 00bf33faa0..4f93946ce2 100644 --- a/src/applications/config/option/PhabricatorUIConfigOptions.php +++ b/src/applications/config/option/PhabricatorUIConfigOptions.php @@ -20,9 +20,6 @@ final class PhabricatorUIConfigOptions } public function getOptions() { - $custom_header_example = - PhabricatorCustomHeaderConfigType::getExampleConfig(); - $experimental_link = 'https://secure.phabricator.com/T4214'; $options = array( 'blindigo' => 'blindigo', 'red' => 'red', @@ -48,11 +45,24 @@ final class PhabricatorUIConfigOptions ] EOJSON; + $logo_type = 'custom:PhabricatorCustomLogoConfigType'; + return array( $this->newOption('ui.header-color', 'enum', 'blindigo') ->setDescription( pht('Sets the default color scheme of Phabricator.')) ->setEnumOptions($options), + $this->newOption('ui.logo', $logo_type, array()) + ->setSummary( + pht('Customize the logo and wordmark text in the header.')) + ->setDescription( + pht( + "Customize the logo image and text which appears in the main ". + "site header:\n\n". + " - **Logo Image**: Upload a new 80 x 80px image to replace the ". + "Phabricator logo in the site header.\n\n". + " - **Wordmark**: Choose new text to display next to the logo. ". + "By default, the header displays //Phabricator//.\n\n")), $this->newOption('ui.footer-items', 'list', array()) ->setSummary( pht( @@ -69,39 +79,6 @@ EOJSON; " omit this if you just want a piece of text, like a copyright ". " notice.")) ->addExample($example, pht('Basic Example')), - $this->newOption('ui.custom-wordmark', 'string', array()) - ->setSummary( - pht( - 'Customize the text next to the logo.')) - ->setDescription( - pht( - "Allows you to change the text (Phabricator by default) ". - "next to the Phabricator logo.\n\n")), - $this->newOption( - 'ui.custom-header', - 'custom:PhabricatorCustomHeaderConfigType', - null) - ->setSummary( - pht('Customize the Phabricator logo.')) - ->setDescription( - pht('You can customize the Phabricator logo by specifying the '. - 'phid for a viewable image you have uploaded to Phabricator '. - 'via the [[ /file/ | Files application]]. This image should '. - 'be:'."\n". - ' - 80px X 80px; while not enforced, images with these '. - 'dimensions will look best across devices.'."\n". - ' - have view policy public if [[ '. - '/config/edit/policy.allow-public | `policy.allow-public`]] '. - 'is true and otherwise view policy user; mismatches in these '. - 'policy settings will result in a broken logo for some users.'. - "\n\n". - 'You should restart Phabricator after updating this value '. - 'to see this change take effect.'. - "\n\n". - 'As this feature is experimental, please read [[ %s | T4214 ]] '. - 'for up to date information.', - $experimental_link)) - ->addExample($custom_header_example, pht('Valid Config')), ); } diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index f353012a5a..c0ebe680dc 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -297,13 +297,13 @@ final class PhabricatorMainMenuView extends AphrontView { } private function renderPhabricatorLogo() { - $style_logo = null; - $logo = null; - $custom_header = PhabricatorEnv::getEnvConfig('ui.custom-header'); - $custom_wordmark = PhabricatorEnv::getEnvConfig('ui.custom-wordmark'); + $custom_header = PhabricatorCustomLogoConfigType::getLogoImagePHID(); + + $logo_style = array(); if ($custom_header) { $cache = PhabricatorCaches::getImmutableCache(); - $cache_key_logo = 'ui.custom-header.logo-phid.v1.'.$custom_header; + $cache_key_logo = 'ui.custom-header.logo-phid.v3.'.$custom_header; + $logo_uri = $cache->getKey($cache_key_logo); if (!$logo_uri) { $file = id(new PhabricatorFileQuery()) @@ -315,31 +315,32 @@ final class PhabricatorMainMenuView extends AphrontView { $cache->setKey($cache_key_logo, $logo_uri); } } - if ($logo_uri) { - $style_logo = - 'background-size: 40px 40px; '. - 'background-position: 0px 0px; '. - 'background-image: url('.$logo_uri.');'; - } - $logo = phutil_tag( - 'span', - array( - 'class' => 'phabricator-main-menu-logo', - 'style' => $style_logo, - ), - ''); + $logo_style[] = 'background-size: 40px 40px;'; + $logo_style[] = 'background-position: 0 0;'; + $logo_style[] = 'background-image: url('.$logo_uri.')'; } - if (!$logo) { - $logo = phutil_tag( - 'span', - array( - 'class' => 'phabricator-wordmark', - ), - (($custom_wordmark) ? $custom_wordmark : pht('Phabricator'))); + $logo_node = phutil_tag( + 'span', + array( + 'class' => 'phabricator-main-menu-eye', + 'style' => implode(' ', $logo_style), + )); + + + $wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark(); + if (!strlen($wordmark_text)) { + $wordmark_text = pht('Phabricator'); } + $wordmark_node = phutil_tag( + 'span', + array( + 'class' => 'phabricator-wordmark', + ), + $wordmark_text); + return phutil_tag( 'a', array( @@ -353,13 +354,8 @@ final class PhabricatorMainMenuView extends AphrontView { 'aural' => true, ), pht('Home')), - phutil_tag( - 'span', - array( - 'class' => 'phabricator-main-menu-eye', - ), - ''), - $logo, + $logo_node, + $wordmark_node, )); } From 679fbada448eead758ab10026dabddea62ca6b54 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 7 Aug 2016 20:04:57 -0700 Subject: [PATCH 03/17] Remove PHUIDocumentView Summary: Converts final call site to PHUIDocumentViewPro. Test Plan: grep for PHUIDocumentView, view new Welcome Page Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16379 --- resources/celerity/map.php | 8 +- src/__phutil_library_map__.php | 4 - .../PhabricatorConfigWelcomeController.php | 7 +- .../examples/PHUIDocumentExample.php | 199 ------------------ src/view/phui/PHUIDocumentView.php | 162 -------------- .../css/application/config/config-welcome.css | 7 +- webroot/rsrc/css/phui/phui-document.css | 55 ----- 7 files changed, 16 insertions(+), 426 deletions(-) delete mode 100644 src/applications/uiexample/examples/PHUIDocumentExample.php delete mode 100644 src/view/phui/PHUIDocumentView.php diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 92360d0793..90914e5cff 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -41,7 +41,7 @@ return array( 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/config/config-options.css' => '0ede4c9b', 'rsrc/css/application/config/config-template.css' => '8e6c6fcd', - 'rsrc/css/application/config/config-welcome.css' => '6abd79be', + 'rsrc/css/application/config/config-welcome.css' => '035aa483', 'rsrc/css/application/config/setup-issue.css' => 'db7e9c40', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/conpherence/durable-column.css' => '86396117', @@ -131,7 +131,7 @@ return array( 'rsrc/css/phui/phui-curtain-view.css' => '7148ae25', 'rsrc/css/phui/phui-document-pro.css' => 'dc3d46ed', 'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf', - 'rsrc/css/phui/phui-document.css' => '715aedfb', + 'rsrc/css/phui/phui-document.css' => 'c32e8dec', 'rsrc/css/phui/phui-feed-story.css' => 'aa49845d', 'rsrc/css/phui/phui-fontkit.css' => '9cda225e', 'rsrc/css/phui/phui-form-view.css' => 'fab0a10f', @@ -546,7 +546,7 @@ return array( 'changeset-view-manager' => 'a2828756', 'conduit-api-css' => '7bc725c4', 'config-options-css' => '0ede4c9b', - 'config-welcome-css' => '6abd79be', + 'config-welcome-css' => '035aa483', 'conpherence-durable-column-view' => '86396117', 'conpherence-menu-css' => 'f99fee4c', 'conpherence-message-pane-css' => '5897d3ac', @@ -835,7 +835,7 @@ return array( 'phui-crumbs-view-css' => '9dac418c', 'phui-curtain-view-css' => '7148ae25', 'phui-document-summary-view-css' => '9ca48bdf', - 'phui-document-view-css' => '715aedfb', + 'phui-document-view-css' => 'c32e8dec', 'phui-document-view-pro-css' => 'dc3d46ed', 'phui-feed-story-css' => 'aa49845d', 'phui-font-icon-base-css' => '6449bce8', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 04c4198008..46990ca97f 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1622,9 +1622,7 @@ phutil_register_library_map(array( 'PHUIDiffTableOfContentsItemView' => 'infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php', 'PHUIDiffTableOfContentsListView' => 'infrastructure/diff/view/PHUIDiffTableOfContentsListView.php', 'PHUIDiffTwoUpInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffTwoUpInlineCommentRowScaffold.php', - 'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php', 'PHUIDocumentSummaryView' => 'view/phui/PHUIDocumentSummaryView.php', - 'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php', 'PHUIDocumentViewPro' => 'view/phui/PHUIDocumentViewPro.php', 'PHUIFeedStoryExample' => 'applications/uiexample/examples/PHUIFeedStoryExample.php', 'PHUIFeedStoryView' => 'view/phui/PHUIFeedStoryView.php', @@ -6270,9 +6268,7 @@ phutil_register_library_map(array( 'PHUIDiffTableOfContentsItemView' => 'AphrontView', 'PHUIDiffTableOfContentsListView' => 'AphrontView', 'PHUIDiffTwoUpInlineCommentRowScaffold' => 'PHUIDiffInlineCommentRowScaffold', - 'PHUIDocumentExample' => 'PhabricatorUIExample', 'PHUIDocumentSummaryView' => 'AphrontTagView', - 'PHUIDocumentView' => 'AphrontTagView', 'PHUIDocumentViewPro' => 'AphrontTagView', 'PHUIFeedStoryExample' => 'PhabricatorUIExample', 'PHUIFeedStoryView' => 'AphrontView', diff --git a/src/applications/config/controller/PhabricatorConfigWelcomeController.php b/src/applications/config/controller/PhabricatorConfigWelcomeController.php index a7d29b913b..6825abba8c 100644 --- a/src/applications/config/controller/PhabricatorConfigWelcomeController.php +++ b/src/applications/config/controller/PhabricatorConfigWelcomeController.php @@ -358,7 +358,7 @@ final class PhabricatorConfigWelcomeController $quick_header = new PHUIRemarkupView( $viewer, pht('=Quick Start Guide')); - return id(new PHUIDocumentView()) + $document = id(new PHUIDocumentViewPro()) ->setHeader($header) ->setFluid(true) ->appendChild($setup_header) @@ -367,6 +367,11 @@ final class PhabricatorConfigWelcomeController ->appendChild($explore) ->appendChild($quick_header) ->appendChild($quick); + + return id(new PHUIBoxView()) + ->setBorder(true) + ->appendChild($document) + ->addClass('mlb'); } private function newItem(AphrontRequest $request, $icon, $content) { diff --git a/src/applications/uiexample/examples/PHUIDocumentExample.php b/src/applications/uiexample/examples/PHUIDocumentExample.php deleted file mode 100644 index 155489b80b..0000000000 --- a/src/applications/uiexample/examples/PHUIDocumentExample.php +++ /dev/null @@ -1,199 +0,0 @@ -getRequest(); - $user = $request->getUser(); - - $action = id(new PHUIListItemView()) - ->setName(pht('Actions')) - ->setType(PHUIListItemView::TYPE_LABEL); - - $action1 = id(new PHUIListItemView()) - ->setName(pht('Edit Document')) - ->setHref('#') - ->setIcon('fa-edit') - ->setType(PHUIListItemView::TYPE_LINK); - - $action2 = id(new PHUIListItemView()) - ->setName(pht('Move Document')) - ->setHref('#') - ->setIcon('fa-arrows') - ->setType(PHUIListItemView::TYPE_LINK); - - $action3 = id(new PHUIListItemView()) - ->setName(pht('Delete Document')) - ->setHref('#') - ->setIcon('fa-times') - ->setType(PHUIListItemView::TYPE_LINK); - - $action4 = id(new PHUIListItemView()) - ->setName(pht('View History')) - ->setHref('#') - ->setIcon('fa-list') - ->setType(PHUIListItemView::TYPE_LINK); - - $action5 = id(new PHUIListItemView()) - ->setName(pht('Subscribe')) - ->setHref('#') - ->setIcon('fa-plus-circle') - ->setType(PHUIListItemView::TYPE_LINK); - - $divider = id(new PHUIListItemView()) - ->setType(PHUIListItemView::TYPE_DIVIDER); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Installation')); - - $label1 = id(new PHUIListItemView()) - ->setName(pht('Getting Started')) - ->setType(PHUIListItemView::TYPE_LABEL); - - $label2 = id(new PHUIListItemView()) - ->setName(pht('Documentation')) - ->setType(PHUIListItemView::TYPE_LABEL); - - $item1 = id(new PHUIListItemView()) - ->setName(pht('Installation')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $item2 = id(new PHUIListItemView()) - ->setName(pht('Webserver Config')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $item3 = id(new PHUIListItemView()) - ->setName(pht('Adding Users')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $item4 = id(new PHUIListItemView()) - ->setName(pht('Debugging')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $sidenav = id(new PHUIListView()) - ->setType(PHUIListView::SIDENAV_LIST) - ->addMenuItem($action) - ->addMenuItem($action1) - ->addMenuItem($action2) - ->addMenuItem($action3) - ->addMenuItem($action4) - ->addMenuItem($action5) - ->addMenuItem($divider) - ->addMenuItem($label1) - ->addMenuItem($item1) - ->addMenuItem($item2) - ->addMenuItem($item3) - ->addMenuItem($item4) - ->addMenuItem($label2) - ->addMenuItem($item2) - ->addMenuItem($item3) - ->addMenuItem($item4) - ->addMenuItem($item1); - - $home = id(new PHUIListItemView()) - ->setIcon('fa-home') - ->setHref('#') - ->setType(PHUIListItemView::TYPE_ICON); - - $item1 = id(new PHUIListItemView()) - ->setName(pht('Installation')) - ->setHref('#') - ->setSelected(true) - ->setType(PHUIListItemView::TYPE_LINK); - - $item2 = id(new PHUIListItemView()) - ->setName(pht('Webserver Config')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $item3 = id(new PHUIListItemView()) - ->setName(pht('Adding Users')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $item4 = id(new PHUIListItemView()) - ->setName(pht('Debugging')) - ->setHref('#') - ->setType(PHUIListItemView::TYPE_LINK); - - $topnav = id(new PHUIListView()) - ->setType(PHUIListView::NAVBAR_LIST) - ->addMenuItem($home) - ->addMenuItem($item1) - ->addMenuItem($item2) - ->addMenuItem($item3) - ->addMenuItem($item4); - - $document = hsprintf( - '

Lorem ipsum dolor sit amet, consectetur adipisicing, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'. - '

Lorem ipsum dolor sit amet, consectetur, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'. - '

Lorem ipsum dolor sit amet, consectetur, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'. - '

Lorem ipsum dolor sit amet, consectetur, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'. - '

Lorem ipsum dolor sit amet, consectetur, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'. - '

Lorem ipsum dolor sit amet, consectetur, '. - 'sed do eiusmod tempor incididunt ut labore et dolore magna '. - 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation '. - 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis '. - 'aute irure dolor in reprehenderit in voluptate velit esse cillum '. - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat '. - 'cupidatat non proident, sunt in culpa qui officia deserunt '. - 'mollit anim id est laborum.

'); - - $content = new PHUIDocumentView(); - $content->setBook(pht('Book or Project Name'), pht('Article')); - $content->setHeader($header); - $content->setFluid(true); - $content->setTopNav($topnav); - $content->setSidenav($sidenav); - $content->appendChild($document); - - return $content; - } -} diff --git a/src/view/phui/PHUIDocumentView.php b/src/view/phui/PHUIDocumentView.php deleted file mode 100644 index 9a076b4b74..0000000000 --- a/src/view/phui/PHUIDocumentView.php +++ /dev/null @@ -1,162 +0,0 @@ -offset = $offset; - return $this; - } - - public function setHeader(PHUIHeaderView $header) { - $header->setTall(true); - $this->header = $header; - return $this; - } - - public function setSideNav(PHUIListView $list, $display = self::NAV_BOTTOM) { - $list->setType(PHUIListView::SIDENAV_LIST); - $this->sidenav = $list; - $this->mobileview = $display; - return $this; - } - - public function setTopNav(PHUIListView $list) { - $list->setType(PHUIListView::NAVBAR_LIST); - $this->topnav = $list; - return $this; - } - - public function setCrumbs(PHUIListView $list) { - $this->crumbs = $list; - return $this; - } - - public function setBook($name, $description) { - $this->bookname = $name; - $this->bookdescription = $description; - return $this; - } - - public function setFluid($fluid) { - $this->fluid = $fluid; - return $this; - } - - protected function getTagAttributes() { - $classes = array(); - - if ($this->offset) { - $classes[] = 'phui-document-offset'; - } - - if ($this->fluid) { - $classes[] = 'phui-document-fluid'; - } - - return array( - 'class' => $classes, - ); - } - - protected function getTagContent() { - require_celerity_resource('phui-document-view-css'); - - $classes = array(); - $classes[] = 'phui-document-view'; - if ($this->offset) { - $classes[] = 'phui-offset-view'; - } - if ($this->sidenav) { - $classes[] = 'phui-sidenav-view'; - } - - $sidenav = null; - if ($this->sidenav) { - $sidenav = phutil_tag( - 'div', - array( - 'class' => 'phui-document-sidenav', - ), - $this->sidenav); - } - - $book = null; - if ($this->bookname) { - $book = pht('%s (%s)', $this->bookname, $this->bookdescription); - } - - $topnav = null; - if ($this->topnav) { - $topnav = phutil_tag( - 'div', - array( - 'class' => 'phui-document-topnav', - ), - $this->topnav); - } - - $crumbs = null; - if ($this->crumbs) { - $crumbs = phutil_tag( - 'div', - array( - 'class' => 'phui-document-crumbs', - ), - $this->bookName); - } - - $main_content = $this->renderChildren(); - - if ($book) { - $this->header->setSubheader($book); - } - $content_inner = phutil_tag( - 'div', - array( - 'class' => 'phui-document-inner', - ), - array( - $this->header, - $topnav, - $main_content, - $crumbs, - )); - - if ($this->mobileview == self::NAV_BOTTOM) { - $order = array($content_inner, $sidenav); - } else { - $order = array($sidenav, $content_inner); - } - - $content = phutil_tag( - 'div', - array( - 'class' => 'phui-document-content', - ), - $order); - - $view = phutil_tag( - 'div', - array( - 'class' => implode(' ', $classes), - ), - $content); - - return $view; - } - -} diff --git a/webroot/rsrc/css/application/config/config-welcome.css b/webroot/rsrc/css/application/config/config-welcome.css index 8410d00500..748726476e 100644 --- a/webroot/rsrc/css/application/config/config-welcome.css +++ b/webroot/rsrc/css/application/config/config-welcome.css @@ -19,5 +19,10 @@ width: 32px; float: left; text-align: center; - margin-left: 16px; } + +.phui-document-view-pro .phui-document-content .config-welcome-box + .phabricator-remarkup { + margin: 0; + padding: 0; + } diff --git a/webroot/rsrc/css/phui/phui-document.css b/webroot/rsrc/css/phui/phui-document.css index 2b75227c42..87cdc60ddd 100644 --- a/webroot/rsrc/css/phui/phui-document.css +++ b/webroot/rsrc/css/phui/phui-document.css @@ -8,15 +8,6 @@ position: relative; } -.phui-document-view .phui-header-shell { - padding: 16px; - background-color: {$bluebackground}; -} - -.phui-document-content { - border-radius: 3px; -} - .device-desktop .phui-document-view { border: 1px solid {$lightblueborder}; max-width: 960px; @@ -33,44 +24,11 @@ margin: 16px; } -.phui-crumbs-view + .phui-document-fluid .phui-document-view { - margin-top: 0; -} - -.device-desktop .phui-document-view.phui-offset-view { - max-width: 800px; -} - /* Fix so that Phriction Document preview is the same width as the document */ .device-desktop .phui-remarkup-preview .phui-document-view { width: 800px; } -.phui-document-sidenav { - position:absolute; - width: 200px; - text-overflow: ellipsis; - top: 0; - right: 0; -} - -.device-phone .phui-document-sidenav { - position: static; - width: auto; - border-top: 1px solid {$thinblueborder}; - border-bottom: 1px solid {$thinblueborder}; -} - -.device-phone .phui-sidenav-view .phui-document-inner { - margin: 0; -} - -.phui-sidenav-view .phui-document-inner { - margin-right: 200px; - border-right: 1px solid {$thinblueborder}; - background: #fff; -} - .phui-document-content .phui-header-shell { border-top: none; border-bottom: 1px solid {$lightblueborder}; @@ -88,11 +46,6 @@ padding: 8px 0 4px; } -.phui-document-content .phui-property-list-container { - border-bottom: 1px solid {$thinblueborder}; - background-color: {$lightgreybackground}; -} - .legalpad .phui-document-content .phui-property-list-view { border: none; box-shadow: none; @@ -127,18 +80,10 @@ margin: 16px 0; } -.device-desktop .phui-document-offset { - padding-right: 120px; -} - .phui-document-view .phui-info-severity-nodata { background-color: {$lightgreybackground}; } -body .phui-document-view .phui-header-shell.phui-bleed-header { - padding: 0; -} - .phui-document-view .phui-property-list-section-header { padding: 20px 24px 0px; border-top: none; From c80933be2f8b14d87521cacbb21c72404a912939 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 8 Aug 2016 09:45:05 -0700 Subject: [PATCH 04/17] Force logotext to nowrap Summary: When using spaces in the logo header, nowrap the text so it properly displays when too long on mobile, tablet. Test Plan: Snowmen Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16380 --- resources/celerity/map.php | 12 ++++++------ webroot/rsrc/css/application/base/main-menu-view.css | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 90914e5cff..82f634330a 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'f12c7d47', + 'core.pkg.css' => '153cb9a1', 'core.pkg.js' => 'b562c3db', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -32,7 +32,7 @@ return array( 'rsrc/css/aphront/typeahead.css' => 'd4f16145', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '0877ed6e', - 'rsrc/css/application/base/main-menu-view.css' => 'a79b6e52', + 'rsrc/css/application/base/main-menu-view.css' => '44a1871b', 'rsrc/css/application/base/notification-menu.css' => 'f31c0bde', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601', 'rsrc/css/application/base/phui-theme.css' => '027ba77e', @@ -783,7 +783,7 @@ return array( 'phabricator-flag-css' => '5337623f', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => '4a021c10', - 'phabricator-main-menu-view' => 'a79b6e52', + 'phabricator-main-menu-view' => '44a1871b', 'phabricator-nav-view-css' => '09f3d0db', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', @@ -1196,6 +1196,9 @@ return array( 'javelin-uri', 'javelin-install', ), + '44a1871b' => array( + 'phui-theme-css', + ), '453c5375' => array( 'javelin-behavior', 'javelin-dom', @@ -1721,9 +1724,6 @@ return array( 'javelin-stratcom', 'javelin-dom', ), - 'a79b6e52' => array( - 'phui-theme-css', - ), 'a80d0378' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index 7496e9a060..4ee1372c16 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -74,6 +74,7 @@ padding-right: 8px; max-width: 175px; overflow: hidden; + white-space: nowrap; } /* - Expand/Collapse Button ---------------------------------------------------- From 325e3b3ff3548832b70be6cd1f075cb460236f44 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 8 Aug 2016 13:21:18 -0700 Subject: [PATCH 05/17] Remove slight wash on transparent background on logo Summary: Very slight gradient behind the eye I didn't catch (extra layer). Test Plan: Remove all layers except logo, re-export. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16381 --- resources/celerity/map.php | 14 +++++++------- webroot/rsrc/image/logo/light-eye.png | Bin 1350 -> 1057 bytes 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 82f634330a..652fea9dde 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => '153cb9a1', + 'core.pkg.css' => 'a012d3c0', 'core.pkg.js' => 'b562c3db', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -32,7 +32,7 @@ return array( 'rsrc/css/aphront/typeahead.css' => 'd4f16145', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '0877ed6e', - 'rsrc/css/application/base/main-menu-view.css' => '44a1871b', + 'rsrc/css/application/base/main-menu-view.css' => '3b0d39f7', 'rsrc/css/application/base/notification-menu.css' => 'f31c0bde', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601', 'rsrc/css/application/base/phui-theme.css' => '027ba77e', @@ -319,7 +319,7 @@ return array( 'rsrc/image/icon/tango/upload.png' => '7bbb7984', 'rsrc/image/icon/unsubscribe.png' => '25725013', 'rsrc/image/lightblue-header.png' => '5c168b6d', - 'rsrc/image/logo/light-eye.png' => 'fcd66408', + 'rsrc/image/logo/light-eye.png' => '1a576ddd', 'rsrc/image/main_texture.png' => '29a2c5ad', 'rsrc/image/menu_texture.png' => '5a17580d', 'rsrc/image/people/harding.png' => '45aa614e', @@ -783,7 +783,7 @@ return array( 'phabricator-flag-css' => '5337623f', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => '4a021c10', - 'phabricator-main-menu-view' => '44a1871b', + 'phabricator-main-menu-view' => '3b0d39f7', 'phabricator-nav-view-css' => '09f3d0db', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', @@ -1162,6 +1162,9 @@ return array( 'javelin-dom', 'javelin-magical-init', ), + '3b0d39f7' => array( + 'phui-theme-css', + ), '3cb0b2fc' => array( 'javelin-behavior', 'javelin-dom', @@ -1196,9 +1199,6 @@ return array( 'javelin-uri', 'javelin-install', ), - '44a1871b' => array( - 'phui-theme-css', - ), '453c5375' => array( 'javelin-behavior', 'javelin-dom', diff --git a/webroot/rsrc/image/logo/light-eye.png b/webroot/rsrc/image/logo/light-eye.png index 19d28b72e72c97b3d35380f0f857cf7b7e423650..772dcb0c01a2c3360861b3229bd63f36fe721074 100644 GIT binary patch delta 1037 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 From f0321465910468c83eb03e1b8effd9170187a475 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Fri, 5 Aug 2016 02:19:21 -0700 Subject: [PATCH 06/17] Convert bin/storage workflow to presume utf8mb4 as the default encoding Summary: see comments on rP68904d941c54 Test Plan: run ,/bin/storage upgrade Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16370 --- .../workflow/PhabricatorStorageManagementShellWorkflow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php index 45f4d2d8e8..84e2ed5489 100644 --- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php @@ -31,7 +31,7 @@ final class PhabricatorStorageManagementShellWorkflow } return phutil_passthru( - 'mysql --protocol=TCP --default-character-set=utf8 '. + 'mysql --protocol=TCP --default-character-set=utf8mb4 '. '-u %s %C -h %s %C', $api->getUser(), $flag_password, From 78ea6641a20470d8e68152f340133673d2506c9e Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 9 Aug 2016 18:01:29 -0700 Subject: [PATCH 07/17] Let everyone view Herald rules Summary: Ref T9410. This changes the view policy for all Herald rules to the most public policy ("All Users" for private installs, "Public" for public installs). See T11428 for discussion of this change in greater detail. In practice, this is //approximately// how things work today anyway, since you can almost always see almost all of this information in transcripts. I believe this narrower view policy is helpful in zero cases and slightly confusing or harmful in a number of reasonable cases. Test Plan: Viewed personal, object and global rules as users who could and could not edit the rules. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9410 Differential Revision: https://secure.phabricator.com/D16382 --- .../controller/HeraldRuleViewController.php | 4 ++ .../herald/storage/HeraldRule.php | 41 ++++++++++--------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/applications/herald/controller/HeraldRuleViewController.php b/src/applications/herald/controller/HeraldRuleViewController.php index 818eb7560f..9e696c23c4 100644 --- a/src/applications/herald/controller/HeraldRuleViewController.php +++ b/src/applications/herald/controller/HeraldRuleViewController.php @@ -2,6 +2,10 @@ final class HeraldRuleViewController extends HeraldController { + public function shouldAllowPublic() { + return true; + } + public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); diff --git a/src/applications/herald/storage/HeraldRule.php b/src/applications/herald/storage/HeraldRule.php index 19f9b95507..cf00e046b7 100644 --- a/src/applications/herald/storage/HeraldRule.php +++ b/src/applications/herald/storage/HeraldRule.php @@ -288,39 +288,40 @@ final class HeraldRule extends HeraldDAO } public function getPolicy($capability) { + if ($capability == PhabricatorPolicyCapability::CAN_VIEW) { + return PhabricatorPolicies::getMostOpenPolicy(); + } + if ($this->isGlobalRule()) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return PhabricatorPolicies::POLICY_USER; - case PhabricatorPolicyCapability::CAN_EDIT: - $app = 'PhabricatorHeraldApplication'; - $herald = PhabricatorApplication::getByClass($app); - $global = HeraldManageGlobalRulesCapability::CAPABILITY; - return $herald->getPolicy($global); - } + $app = 'PhabricatorHeraldApplication'; + $herald = PhabricatorApplication::getByClass($app); + $global = HeraldManageGlobalRulesCapability::CAPABILITY; + return $herald->getPolicy($global); } else if ($this->isObjectRule()) { return $this->getTriggerObject()->getPolicy($capability); } else { - return PhabricatorPolicies::POLICY_NOONE; + return $this->getAuthorPHID(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - if ($this->isPersonalRule()) { - return ($viewer->getPHID() == $this->getAuthorPHID()); - } else { - return false; - } + return false; } public function describeAutomaticCapability($capability) { - if ($this->isPersonalRule()) { - return pht("A personal rule's owner can always view and edit it."); - } else if ($this->isObjectRule()) { - return pht('Object rules inherit the policies of their objects.'); + if ($capability == PhabricatorPolicyCapability::CAN_VIEW) { + return null; } - return null; + if ($this->isGlobalRule()) { + return pht( + 'Global Herald rules can be edited by users with the "Can Manage '. + 'Global Rules" Herald application permission.'); + } else if ($this->isObjectRule()) { + return pht('Object rules inherit the edit policies of their objects.'); + } else { + return pht('A personal rule can only be edited by its owner.'); + } } From 7de2fae15611f1e104d631df19555edeb695d3c7 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 9 Aug 2016 18:22:00 -0700 Subject: [PATCH 08/17] Link Herald rules to rule detail pages in Herald transcripts Summary: Fixes T9410. Depends on D16382. Since all users can now view all Herald rules, we can link them in the transcripts. Test Plan: Viewed a transcript, clicked rule names, reviewed rules. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9410 Differential Revision: https://secure.phabricator.com/D16383 --- .../herald/controller/HeraldTranscriptController.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/applications/herald/controller/HeraldTranscriptController.php b/src/applications/herald/controller/HeraldTranscriptController.php index e15c7ed52c..a9509beb33 100644 --- a/src/applications/herald/controller/HeraldTranscriptController.php +++ b/src/applications/herald/controller/HeraldTranscriptController.php @@ -249,9 +249,13 @@ final class HeraldTranscriptController extends HeraldController { foreach ($rule_xscripts as $rule_xscript) { $rule_id = $rule_xscript->getRuleID(); + $rule_monogram = pht('H%d', $rule_id); + $rule_uri = '/'.$rule_monogram; + $rule_item = id(new PHUIObjectItemView()) - ->setObjectName(pht('H%d', $rule_id)) - ->setHeader($rule_xscript->getRuleName()); + ->setObjectName($rule_monogram) + ->setHeader($rule_xscript->getRuleName()) + ->setHref($rule_uri); if (!$rule_xscript->getResult()) { $rule_item->setDisabled(true); From 38403b12beb63cf6c183743489353458122be3af Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 10 Aug 2016 06:51:39 -0700 Subject: [PATCH 09/17] Update Herald documentation for modern policies and beahvior Summary: Ref T11428. This documentation was a bit misleading and out of date. Update it to reflect modern reality. Test Plan: Read documentation. Reviewers: chad Reviewed By: chad Maniphest Tasks: T11428 Differential Revision: https://secure.phabricator.com/D16384 --- src/docs/user/userguide/herald.diviner | 198 +++++++++++++++---------- 1 file changed, 120 insertions(+), 78 deletions(-) diff --git a/src/docs/user/userguide/herald.diviner b/src/docs/user/userguide/herald.diviner index be4992cf4d..6c5c6239cb 100644 --- a/src/docs/user/userguide/herald.diviner +++ b/src/docs/user/userguide/herald.diviner @@ -3,96 +3,138 @@ Use Herald to get notified of changes you care about. -= Overview = +Overview +======== -Herald allows you to write processing rules that take effect when objects (such -as Differential revisions and commits) are created or updated. For instance, you -might want to get notified every time someone sends out a revision that affects -some file you're interested in, even if they didn't add you as a reviewer. +Herald allows you to write rules which run automatically when objects (like +tasks or commits) are created or updated. For instance, you might want to get +notified every time someone sends out a revision that affects some file you're +interested in, even if they didn't add you as a reviewer. -Herald is less useful for small organizations (where everyone will generally -know most of what's going on) but the usefulness of the application increases -as an organization scales. Once there is too much activity to keep track of it -all, Herald allows you to filter it down so you're only notified of things you -are interested in. - -= Global and Personal Rules = - -You can create two kinds of Herald rules, //global// and //personal//: - - - **Personal Rules** are rules you own, but they can only affect you. Only - you can edit or delete personal rules, but their actions are limited to - adding you to CC, subscribing you, etc. - - **Global Rules** are rules everyone owns, and they can affect anything. - Anyone can edit or delete a global rule, and they can take any action, - including affecting projects and mailing lists. - -The general idea is to prevent individuals from controlling rules that affect -shared resources, so if a rule needs to be updated it's not a big deal if the -person who created it is on vacation. - -= Rules, Conditions and Actions = - -The best way to think of Herald is as a system similar to the mail rules you can -set up in most email clients, to organize mail based on "To", "Subject", etc. +One way to think about Herald is that it is a lot like the mail rules you can +set up in most email clients to organize mail based on "To", "Subject", etc. Herald works very similarly, but operates on Phabricator objects (like revisions and commits) instead of emails. -Every time an object is created or updated, Herald rules are run on it and -the actions for any matching rules are taken. +For example, you can write a personal rule like this which triggers on tasks: -To create a new Herald rule, choose which type of event you want to act on -(e.g., changes to Differential Revisions, or Commits), and then set a list of -conditions. For example, you might add the condition `Author is alincoln -(Abraham Lincoln)` to keep track of everything alincoln does. Finally, set -a list of actions to take when the conditions match, like adding yourself to the -CC list. +> When [ all of ] these conditions are met: +> [ Title ][ contains ][ quasar ] +> Take these actions [ every time ] this rule matches: +> [ Add me as a subscriber ] -Now you'll automatically be added to CC any time alincoln creates a revision, -and can keep an eye on what he's up to. +This rule will automatically subscribe you to any newly created or updated +tasks that contain "quasar" in the title. -= Available Actions = +Herald rules are often used to: notify users, add reviewers, initiate audits, +classify objects, block commits, enforce CLAs, and run builds. -Herald rules can take a number of actions. Note that some actions are only -available from Global rules, and others only from Personal rules. Additionally, -not every action is available for every object type (for instance, you can not -trigger an audit based on a Differential revision). - - **Add CC**: Add a user or mailing list to the CC list for the object. For - personal rules, you can only add yourself. - - **Remove CC**: Remove a user or mailing list from the CC list for the - object. For personal rules, you can only remove yourself. - - **Send an Email to**: Send one email, but don't subscribe to other updates. - For personal rules, you can only email yourself. - - **Trigger an Audit**: For commits, trigger an audit request for a project - or user. For personal rules, you can only trigger an audit request to - yourself. - - **Mark with flag**: Flag the object for later review. This action is only - available on personal rules. If an object already has a flag, this action - will not add another flag. - - **Do Nothing**: Don't do anything. This can be used to disable a rule - temporarily, or to create a rule for an "Another Herald rule" condition. +Working with Rules +================== -= Testing Rules = +To create new Herald rules, navigate to the {nav Herald} application and select +{nav Create Herald Rule}. -When you've created a rule, use the "Test Console" to test it out. Enter a -revision or commit and Herald will do a dry run against that object, showing -you which rules //would// match had it actually been updated. Dry runs executed -via the test console don't take any actions. +Next, you'll choose an event that you want to write a rule for: for example, +a rule for when commits are discovered or a rule for when tasks are created or +updated. -= Advanced Herald = +After selecting an event, choose the type of rule to create. See "Rule Types" +below for a more detailed discussion. -A few features in Herald are particularly complicated: +Name the rule and provide conditions and actions. When events occur, the rule +will be evaluated automatically. If the conditions pass, the actions will be +taken. - - **matches regexp pair**: for Differential revisions, you can set a condition - like "Any changed file content matches regexp pair...". This allows you to - specify two regexes in JSON format. The first will be used to match the - filename of the changed file; the second will be used to match the content. - For example, if you want to match revisions which add or remove calls to - a "muffinize" function, //but only in JS files//, you can set the value - to `["/\\.js$/", "/muffinize/"]` or similar. - - **Another Herald rule**: you can create Herald rules which depend on other - rules. This can be useful if you need to express a more complicated predicate - than "all" vs "any" allows, or have a common set of conditions which you want - to share between several rules. If a rule is only being used as a group of - conditions, you can set the action to "Do Nothing". +To test rules, use {nav Herald > Test Console}. See "Testing Rules" below +for greater detail. + +To review which rules did or did not trigger for a particular event (and why), +see {nav Herald > Transcripts}. + + +Rule Types +========== + +You can create three kinds of Herald rules: personal rules, object rules, and +global rules. + + - **Personal Rules** are rules owned by an individual. They're often used + to keep people informed about changes they're interested in. + - **Object Rules** are rules associated with an object (like a repository + or project). These are similar to global rules. + - **Global Rules** are apply to all objects. They're often used to block + commits or run builds. + + +Rule Policies +============= + +All Herald rules are always visible to all users. + +The edit policy for a rule depends on what type of rule it is: + + - Personal rules are owned by a particular user, and can only be created or + edited by that user. + - Object rules are associated with a particular object (like a repository), + and can only be created or edited by users who can edit that object. That + is, if you can edit a repository, you can also create object rules for it + and edit existing object rules. + - Global rules are administrative and can only be created or edited by users + with the **Can Manage Global Rules** Herald application permission. + +When rules are about to evaluate, they may first perform some policy tests. + + - Personal rules check if the owning user can see the object which the rule + is about to run on. If the user can not see the object, the rule does not + run. This prevents individuals from writing rules which give them access + to information they don't have permission to see. + - Object and global rules **bypass policies** and always execute. This makes + them very powerful, and is why the **Can Manage Global Rules** policy is + restricted by default. + + +Testing Rules +============= + +When you've created a rule, use the {nav Herald > Test Console} to test it out. + +Enter an object name (like `D123`, `rXYZabcdef`, or `T456`) and Herald will +execute a dry run against that object, showing you which rules //would// match +had it actually been updated. Dry runs executed via the test console don't take +any actions. + + +Advanced Herald +=============== + +A few features in Herald are particularly complicated or unintuitive. + +Condition **matches regexp pair**: Some conditions allow you to select the +operator "matches regexp pair". For example, you can write a rule against +revisions like this one: + +> When [ all of ] these conditions are met: +> [ Changed file content ][ matches regexp pair ][ ... ] + +This condition allows you to specify two regexes in JSON format. The first will +be used to match the filename of the changed file; the second will be used to +match the content. You can use these together to express conditions like +"content in Javascript files". + +For example, if you want to match revisions which add or remove calls to a +"muffinize" function, //but only in JS files//, you can set the value to +`["/\\.js$/", "/muffinize/"]` or similar. This condition is satisfied only +when the filename matches the first expression and the conent matches the +second expression. + +**Another Herald rule**: you can create Herald rules which depend on other +rules. + +This can be useful if you need to express a more complicated condition +than "all" vs "any" allows, or have a common set of conditions which you want +to share between several rules. + +If a rule is only being used as a group of conditions, you can set the action +to "Do Nothing". From e8083ad63a32cde0bd5fb1ff6053a7d973aeaf94 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 10 Aug 2016 09:22:35 -0700 Subject: [PATCH 10/17] Increase the storage size for commit summaries Summary: Fixes T11453. Currently, commit message summaries are limited to 80 bytes. This may only be 20-40 characters for CJK languages or langauges with Cyrillic script. Increase storage size to 255, then truncate to the shorter of 255 bytes or 80 glyphs. This preserves the same behavior for latin languages, but is less tight for Russian, etc. Some minor additional changes: - Provide a way to ask "how much data fits in this column?" so we don't have to duplicate column lengths across summary checks or UI errors like "title too long". - Remove the `text80` datatype, since no other columns use it and we have no use cases (or likely use cases) for it. Test Plan: - Made a commit with a Cyrillic title, saw reasonable summarization in UI: {F1757522} - Added and ran unit tests. - Grepped for removed `SUMMARY_MAX_LENGTH` constant. - Grepped for removed `text80` data type. Reviewers: avivey, chad Reviewed By: avivey Subscribers: avivey Maniphest Tasks: T11453 Differential Revision: https://secure.phabricator.com/D16385 --- .../20160810.commit.01.summarylength.sql | 2 + src/__phutil_library_map__.php | 2 + .../schema/PhabricatorConfigSchemaSpec.php | 27 +++++++++++-- .../storage/PhabricatorRepositoryCommit.php | 2 +- .../PhabricatorRepositoryCommitData.php | 12 +++--- .../PhabricatorRepositoryCommitTestCase.php | 38 +++++++++++++++++++ src/infrastructure/storage/lisk/LiskDAO.php | 18 ++++++++- 7 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 resources/sql/autopatches/20160810.commit.01.summarylength.sql create mode 100644 src/applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php diff --git a/resources/sql/autopatches/20160810.commit.01.summarylength.sql b/resources/sql/autopatches/20160810.commit.01.summarylength.sql new file mode 100644 index 0000000000..366f0948cd --- /dev/null +++ b/resources/sql/autopatches/20160810.commit.01.summarylength.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_repository.repository_commit + CHANGE summary summary VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT}; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 46990ca97f..fc75e65838 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3381,6 +3381,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitPHIDType' => 'applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php', 'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitParserWorker.php', 'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php', + 'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php', 'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php', 'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php', 'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php', @@ -8338,6 +8339,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker', 'PhabricatorRepositoryCommitRef' => 'Phobject', + 'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', diff --git a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php index 740402524a..e29795b98b 100644 --- a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php +++ b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php @@ -70,7 +70,12 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { } $details = $this->getDetailsForDataType($type); - list($column_type, $charset, $collation, $nullable, $auto) = $details; + + $column_type = $details['type']; + $charset = $details['charset']; + $collation = $details['collation']; + $nullable = $details['nullable']; + $auto = $details['auto']; $column = $this->newColumn($name) ->setDataType($type) @@ -182,11 +187,17 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { ->setName($name); } + public function getMaximumByteLengthForDataType($data_type) { + $info = $this->getDetailsForDataType($data_type); + return idx($info, 'bytes'); + } + private function getDetailsForDataType($data_type) { $column_type = null; $charset = null; $collation = null; $auto = false; + $bytes = null; // If the type ends with "?", make the column nullable. $nullable = false; @@ -211,7 +222,6 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { 'text255' => true, 'text160' => true, 'text128' => true, - 'text80' => true, 'text64' => true, 'text40' => true, 'text32' => true, @@ -237,6 +247,10 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { $type = $matches[1]; $size = idx($matches, 2); + if ($size) { + $bytes = $size; + } + switch ($type) { case 'text': if ($is_binary) { @@ -363,7 +377,14 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { } } - return array($column_type, $charset, $collation, $nullable, $auto); + return array( + 'type' => $column_type, + 'charset' => $charset, + 'collation' => $collation, + 'nullable' => $nullable, + 'auto' => $auto, + 'bytes' => $bytes, + ); } } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index ae43c67416..f2ae90d9f3 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -108,7 +108,7 @@ final class PhabricatorRepositoryCommit 'mailKey' => 'bytes20', 'authorPHID' => 'phid?', 'auditStatus' => 'uint32', - 'summary' => 'text80', + 'summary' => 'text255', 'importStatus' => 'uint32', ), self::CONFIG_KEY_SCHEMA => array( diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php index 705634895b..3a4c3a75f5 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php @@ -2,12 +2,6 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { - /** - * NOTE: We denormalize this into the commit table; make sure the sizes - * match up. - */ - const SUMMARY_MAX_LENGTH = 80; - protected $commitID; protected $authorName = ''; protected $commitMessage = ''; @@ -38,10 +32,14 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { } public static function summarizeCommitMessage($message) { + $max_bytes = id(new PhabricatorRepositoryCommit()) + ->getColumnMaximumByteLength('summary'); + $summary = phutil_split_lines($message, $retain_endings = false); $summary = head($summary); $summary = id(new PhutilUTF8StringTruncator()) - ->setMaximumBytes(self::SUMMARY_MAX_LENGTH) + ->setMaximumBytes($max_bytes) + ->setMaximumGlyphs(80) ->truncateString($summary); return $summary; diff --git a/src/applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php b/src/applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php new file mode 100644 index 0000000000..d7715564ce --- /dev/null +++ b/src/applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php @@ -0,0 +1,38 @@ + 0, + 'a' => 1, + str_repeat('a', 81) => 82, + str_repeat('a', 255) => 82, + str_repeat('aa ', 30) => 80, + str_repeat($zhe, 300) => 161, + str_repeat($snowman, 300) => 240, + str_repeat($boar, 300) => 255, + ); + + foreach ($map as $input => $expect) { + $actual = PhabricatorRepositoryCommitData::summarizeCommitMessage( + $input); + $this->assertEqual($expect, strlen($actual)); + } + + } + +} diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php index 88c3e83e74..cf30dc35bc 100644 --- a/src/infrastructure/storage/lisk/LiskDAO.php +++ b/src/infrastructure/storage/lisk/LiskDAO.php @@ -1831,7 +1831,6 @@ abstract class LiskDAO extends Phobject { return $this->getConfigOption(self::CONFIG_BINARY); } - public function getSchemaColumns() { $custom_map = $this->getConfigOption(self::CONFIG_COLUMN_SCHEMA); if (!$custom_map) { @@ -1953,4 +1952,21 @@ abstract class LiskDAO extends Phobject { return $custom_map + $default_map; } + public function getColumnMaximumByteLength($column) { + $map = $this->getSchemaColumns(); + + if (!isset($map[$column])) { + throw new Exception( + pht( + 'Object (of class "%s") does not have a column "%s".', + get_class($this), + $column)); + } + + $data_type = $map[$column]; + + return id(new PhabricatorStorageSchemaSpec()) + ->getMaximumByteLengthForDataType($data_type); + } + } From 3b45608c78f1eb1975cf178c1070827ca1deee94 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 10 Aug 2016 11:54:27 -0700 Subject: [PATCH 11/17] Fix misleading error message when only cluster database masters are configured Summary: Fixes T11446. We can raise the misleading error: > No valid databases are configured! ...when a valid master is configured but unreachable. Instead, more carefully raise either "nothing is configured" or "nothing is reachable". Test Plan: Configured only a master, artificially severed it, got "nothing is reachable" instead of "nothing is configured". Reviewers: chad Reviewed By: chad Maniphest Tasks: T11446 Differential Revision: https://secure.phabricator.com/D16386 --- .../storage/lisk/PhabricatorLiskDAO.php | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php b/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php index 99f1bcb864..21fabed8a8 100644 --- a/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php +++ b/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php @@ -122,15 +122,16 @@ abstract class PhabricatorLiskDAO extends LiskDAO { } $replica = PhabricatorDatabaseRef::getReplicaDatabaseRef(); - if (!$replica) { - throw new Exception( - pht('No valid databases are configured!')); + if ($replica) { + $connection = $replica->newApplicationConnection($database); + $connection->setReadOnly(true); + if ($replica->isReachable($connection)) { + return $connection; + } } - $connection = $replica->newApplicationConnection($database); - $connection->setReadOnly(true); - if ($replica->isReachable($connection)) { - return $connection; + if (!$master && !$replica) { + $this->raiseUnconfigured($database); } $this->raiseUnreachable($database); @@ -153,10 +154,18 @@ abstract class PhabricatorLiskDAO extends LiskDAO { $database)); } + private function raiseUnconfigured($database) { + throw new Exception( + pht( + 'Unable to establish a connection to any database host '. + '(while trying "%s"). No masters or replicas are configured.', + $database)); + } + private function raiseUnreachable($database) { throw new PhabricatorClusterStrandedException( pht( - 'Unable to establish a connection to ANY database host '. + 'Unable to establish a connection to any database host '. '(while trying "%s"). All masters and replicas are completely '. 'unreachable.', $database)); From 5e3efca08a57554535dafd47d55ce38aa83c4b00 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Aug 2016 08:47:47 -0700 Subject: [PATCH 12/17] In taskmaster daemons, only close connections which were not used recently Summary: Ref T11458. Depends on D16388. Currently, we're very aggressive about closing connections in the taskmaster daemons. This can end up taking up a lot of resources. In particular, because the outgoing port for outbound connections normally can not be reused for 60 seconds after a connection closes, we may exhaust outbound ports on the host if there's a big queue full of stuff that's being processed very quickly. At a minimum, we //always// are holding open a `worker` connection, which we always need again right away. So even in the best case we end up opening/closing this about once per second and each daemon takes up about ~60 outbound ports when it should take up ~1. So, make two adjustments: - First, only close connections which we haven't issued a query on in the last 60 seconds. This should prevent us from closing connections that we'll need again immediately in most cases. In the worst case, we shouldn't be eating up any extra ports under default TCP behavior. - Second, explicitly close connections. We were relying on implicit/GC behavior (maybe as a holdover from very long ago, before we got connection wrappers in place?), which probably did about the same thing but isn't as predictable and can't be profiled or instrumented. Test Plan: This is somewhat difficult to test completely convincingly in isolation since the problem behavior depends on production scales and the workload, and to some degree on configuration. I tested that this stuff baiscally works by adding logging to connect/close and running the daemons, verifying that they churned connections a lot before this change (e.g., ~1/s even at no load) and churn rarely afterward (e.g., almost never at no load). I ran some workload through them to make sure I didn't completely break anything. The best real test is just seeing how production responds. Current inbound/outbound connections on `secure001` are 1,200: ``` secure001 $ netstat -t | grep :mysql | wc -l 1164 ``` Current outbound from `repo001` are 18,600: ``` repo001 $ netstat -t | grep :mysql | wc -l 18663 ``` Reviewers: chad Reviewed By: chad Maniphest Tasks: T11458 Differential Revision: https://secure.phabricator.com/D16389 --- .../daemon/PhabricatorDaemon.php | 2 +- src/infrastructure/storage/lisk/LiskDAO.php | 49 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/infrastructure/daemon/PhabricatorDaemon.php b/src/infrastructure/daemon/PhabricatorDaemon.php index 349e0f0ffe..6fd2ed6016 100644 --- a/src/infrastructure/daemon/PhabricatorDaemon.php +++ b/src/infrastructure/daemon/PhabricatorDaemon.php @@ -11,7 +11,7 @@ abstract class PhabricatorDaemon extends PhutilDaemon { } protected function willSleep($duration) { - LiskDAO::closeAllConnections(); + LiskDAO::closeInactiveConnections(60); return; } diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php index cf30dc35bc..e795777394 100644 --- a/src/infrastructure/storage/lisk/LiskDAO.php +++ b/src/infrastructure/storage/lisk/LiskDAO.php @@ -1621,10 +1621,55 @@ abstract class LiskDAO extends Phobject { return (bool)self::$transactionIsolationLevel; } - public static function closeAllConnections() { - self::$connections = array(); + /** + * Close any connections with no recent activity. + * + * Long-running processes can use this method to clean up connections which + * have not been used recently. + * + * @param int Close connections with no activity for this many seconds. + * @return void + */ + public static function closeInactiveConnections($idle_window) { + $connections = self::$connections; + + $now = PhabricatorTime::getNow(); + foreach ($connections as $key => $connection) { + $last_active = $connection->getLastActiveEpoch(); + + $idle_duration = ($now - $last_active); + if ($idle_duration <= $idle_window) { + continue; + } + + self::closeConnection($key); + } } + + public static function closeAllConnections() { + $connections = self::$connections; + + foreach ($connections as $key => $connection) { + self::closeConnection($key); + } + } + + private static function closeConnection($key) { + if (empty(self::$connections[$key])) { + throw new Exception( + pht( + 'No database connection with connection key "%s" exists!', + $key)); + } + + $connection = self::$connections[$key]; + unset(self::$connections[$key]); + + $connection->close(); + } + + /* -( Utilities )---------------------------------------------------------- */ From 39d4e21eec564e91ed05caf23adb046613eb7703 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Aug 2016 15:07:17 -0700 Subject: [PATCH 13/17] Fix a bad DiffusionCommandEngine parameter from HTTPEngine conversion Summary: I converted this call incorrectly in D16092. We should pass the `PhutilURI` object, not the string version of it. Specifically, this resulted in hitting an error like this if a replica needed synchronization: ``` [2016-08-11 21:22:37] EXCEPTION: (InvalidArgumentException) Argument 1 passed to DiffusionCommandEngine::setURI() must be an instance of PhutilURI, string given, called in... #0 PhutilErrorHandler::handleError(integer, string, string, integer, array) called at [/src/applications/diffusion/protocol/DiffusionCommandEngine.php:52] #1 DiffusionCommandEngine::setURI(string) called at [/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php:601] ... ``` Test Plan: Clusterized an observed repository, demoted a node, ran `bin/repository update Rxxx` to update, saw no typehint fatal. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16390 --- .../diffusion/protocol/DiffusionRepositoryClusterEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php b/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php index 026558f1b8..6fa0bac9e8 100644 --- a/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php +++ b/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php @@ -598,7 +598,7 @@ final class DiffusionRepositoryClusterEngine extends Phobject { ->setArgv($argv) ->setSudoAsDaemon(true) ->setCredentialPHID($repository->getCredentialPHID()) - ->setURI($repository->getRemoteURI()) + ->setURI($repository->getRemoteURIObject()) ->newFuture(); $future->setCWD($local_path); From ca78c1825a665c8c3a37cc10331e8300c40e3e2a Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Aug 2016 16:02:57 -0700 Subject: [PATCH 14/17] When already running as the daemon user, don't "sudo" daemon commands Summary: The cluster synchronization code runs either actively (before returning a response to `git clone`, for example) or passively (routinely, as the daemons update reposiories). The active sync runs as the web user (if running `git clone http://...`) or the VCS user (if running `git clone ssh://...`). But the passive sync runs as the daemon user. All of these sync processes need to run actual commands as the daemon user (`git fetch ...`). For the active ones, we must `sudo`. For the passive ones, we're already the right user. We run the same code, and end up trying to sudo to ourselves, which `sudo` isn't happy about by default. Depending on how `sudo` is configured and which users things are running as this might work anyway, but it's silly and if it doesn't work it requires you to go make non-obvious, weird config changes that are unintuitive and somewhat nonsensical. This is probably worse on the balance than adding a bit of complexity to the code. Instead, test which user we're running as. If it's already the right user, don't sudo. Test Plan: - Ran `bin/repository update --trace` as daemon user, saw no more `sudo`. - Ran a `git clone` to make sure that didn't break. Reviewers: chad, avivey Reviewed By: avivey Differential Revision: https://secure.phabricator.com/D16391 --- .../daemon/PhabricatorDaemon.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/infrastructure/daemon/PhabricatorDaemon.php b/src/infrastructure/daemon/PhabricatorDaemon.php index 6fd2ed6016..f42a59f134 100644 --- a/src/infrastructure/daemon/PhabricatorDaemon.php +++ b/src/infrastructure/daemon/PhabricatorDaemon.php @@ -34,6 +34,24 @@ abstract class PhabricatorDaemon extends PhutilDaemon { return $command; } + // We may reach this method while already running as the daemon user: for + // example, active and passive synchronization of clustered repositories + // run the same commands through the same code, but as different users. + + // By default, `sudo` won't let you sudo to yourself, so we can get into + // trouble if we're already running as the daemon user unless the host has + // been configured to let the daemon user run commands as itself. + + // Since this is silly and more complicated than doing this check, don't + // use `sudo` if we're already running as the correct user. + if (function_exists('posix_getuid')) { + $uid = posix_getuid(); + $info = posix_getpwuid($uid); + if ($info && $info['name'] == $user) { + return $command; + } + } + // Get the absolute path so we're safe against the caller wiping out // PATH. $sudo = Filesystem::resolveBinary('sudo'); From 67861ec1978418fd6daccad64f0878ba5084d7bb Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Aug 2016 16:14:17 -0700 Subject: [PATCH 15/17] List both hosted and observed repositories in "Cluster Repository Status" configuration console Summary: When I wrote this the first time, only hosted repositories could be clustered. This check wasn't removed when I allowed observed repositories to be clustered in D15986. Test Plan: Reloaded {nav Config > Repository Servers} page, saw more stuff locally. Reviewed the cardinal digits between 1 and 17, inclusive. Reviewers: chad, avivey Reviewed By: avivey Differential Revision: https://secure.phabricator.com/D16392 --- .../PhabricatorConfigClusterRepositoriesController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php index d03d58a954..bea1a0dec6 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php @@ -43,7 +43,6 @@ final class PhabricatorConfigClusterRepositoriesController $all_repositories = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) - ->withHosted(PhabricatorRepositoryQuery::HOSTED_PHABRICATOR) ->withTypes( array( PhabricatorRepositoryType::REPOSITORY_TYPE_GIT, From 07ea4e6f74e2173f3b4034e100305533bc43d7b0 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 11 Aug 2016 17:12:53 -0700 Subject: [PATCH 16/17] Fix scrollbar in filetree sidenav Summary: Fixes T11457, I guess. It feels wierd when you drag it a bit, and Im not positive if it's the calc css or javascript. Test Plan: Enable filetree, shorten browser, see scrolling appear if files too long. Reviewers: avivey, epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T11457 Differential Revision: https://secure.phabricator.com/D16393 --- resources/celerity/map.php | 6 +++--- webroot/rsrc/css/aphront/phabricator-nav-view.css | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 652fea9dde..9296082d99 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'a012d3c0', + 'core.pkg.css' => '340c5b75', 'core.pkg.js' => 'b562c3db', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -24,7 +24,7 @@ return array( 'rsrc/css/aphront/multi-column.css' => 'fd18389d', 'rsrc/css/aphront/notification.css' => '3f6c89c9', 'rsrc/css/aphront/panel-view.css' => '8427b78d', - 'rsrc/css/aphront/phabricator-nav-view.css' => '09f3d0db', + 'rsrc/css/aphront/phabricator-nav-view.css' => 'b29426e9', 'rsrc/css/aphront/table-view.css' => '832656fd', 'rsrc/css/aphront/tokenizer.css' => '056da01b', 'rsrc/css/aphront/tooltip.css' => '1a07aea8', @@ -784,7 +784,7 @@ return array( 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => '4a021c10', 'phabricator-main-menu-view' => '3b0d39f7', - 'phabricator-nav-view-css' => '09f3d0db', + 'phabricator-nav-view-css' => 'b29426e9', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', 'phabricator-notification-menu-css' => 'f31c0bde', diff --git a/webroot/rsrc/css/aphront/phabricator-nav-view.css b/webroot/rsrc/css/aphront/phabricator-nav-view.css index 760c2cd372..0846a1a4fe 100644 --- a/webroot/rsrc/css/aphront/phabricator-nav-view.css +++ b/webroot/rsrc/css/aphront/phabricator-nav-view.css @@ -68,6 +68,12 @@ margin-left: 212px; } +.has-drag-nav ul.phui-list-view { + height: 100%; + overflow-y: auto; + overflow-x: hidden; +} + .device-desktop .phui-navigation-shell .has-drag-nav .phabricator-nav-local { width: 205px; padding: 0; From 65e964fca14ded8b5c857691ebba48327797d7d7 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 11 Aug 2016 20:04:25 -0700 Subject: [PATCH 17/17] Make "Core Applications" more reasonable Summary: Ref T11132, cleaning up what "Core Applications" means. Test Plan: Visit `/applications/`, see less poseurs. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T11132 Differential Revision: https://secure.phabricator.com/D16394 --- .../calendar/application/PhabricatorCalendarApplication.php | 4 ++++ .../feed/application/PhabricatorFeedApplication.php | 4 ++++ .../packages/application/PhabricatorPackagesApplication.php | 4 ++++ .../people/application/PhabricatorPeopleApplication.php | 4 ++++ .../phurl/application/PhabricatorPhurlApplication.php | 4 ++++ .../ponder/application/PhabricatorPonderApplication.php | 4 ++++ .../releeph/application/PhabricatorReleephApplication.php | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php index 16e6daf3bf..8dd68c42e0 100644 --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -28,6 +28,10 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication { return "\xE2\x8C\xA8"; } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function isPrototype() { return true; } diff --git a/src/applications/feed/application/PhabricatorFeedApplication.php b/src/applications/feed/application/PhabricatorFeedApplication.php index f24ff76fe4..287cf2d387 100644 --- a/src/applications/feed/application/PhabricatorFeedApplication.php +++ b/src/applications/feed/application/PhabricatorFeedApplication.php @@ -18,6 +18,10 @@ final class PhabricatorFeedApplication extends PhabricatorApplication { return 'fa-newspaper-o'; } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function canUninstall() { return false; } diff --git a/src/applications/packages/application/PhabricatorPackagesApplication.php b/src/applications/packages/application/PhabricatorPackagesApplication.php index 7a100e82b8..9de74dddc0 100644 --- a/src/applications/packages/application/PhabricatorPackagesApplication.php +++ b/src/applications/packages/application/PhabricatorPackagesApplication.php @@ -22,6 +22,10 @@ final class PhabricatorPackagesApplication extends PhabricatorApplication { return 'fa-gift'; } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function isPrototype() { return true; } diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php index adc3d87560..44672edd3c 100644 --- a/src/applications/people/application/PhabricatorPeopleApplication.php +++ b/src/applications/people/application/PhabricatorPeopleApplication.php @@ -30,6 +30,10 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication { return pht('Sort of a social utility.'); } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function canUninstall() { return false; } diff --git a/src/applications/phurl/application/PhabricatorPhurlApplication.php b/src/applications/phurl/application/PhabricatorPhurlApplication.php index 763a85173c..59f8f1546f 100644 --- a/src/applications/phurl/application/PhabricatorPhurlApplication.php +++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php @@ -26,6 +26,10 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication { return true; } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function getRemarkupRules() { return array( new PhabricatorPhurlRemarkupRule(), diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php index 616eda10c9..ced8606e99 100644 --- a/src/applications/ponder/application/PhabricatorPonderApplication.php +++ b/src/applications/ponder/application/PhabricatorPonderApplication.php @@ -34,6 +34,10 @@ final class PhabricatorPonderApplication extends PhabricatorApplication { ); } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function supportsEmailIntegration() { return true; } diff --git a/src/applications/releeph/application/PhabricatorReleephApplication.php b/src/applications/releeph/application/PhabricatorReleephApplication.php index ab5a12dc80..2590478f1a 100644 --- a/src/applications/releeph/application/PhabricatorReleephApplication.php +++ b/src/applications/releeph/application/PhabricatorReleephApplication.php @@ -18,6 +18,10 @@ final class PhabricatorReleephApplication extends PhabricatorApplication { return 'fa-flag-checkered'; } + public function getApplicationGroup() { + return self::GROUP_UTILITIES; + } + public function isPrototype() { return true; }