Select the types of activity you want to include in your feed.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
···31313232 // The username to use when connecting to MySQL.
3333 'mysql.user' => 'root',
3434-3434+3535 // The password to use when connecting to MySQL.
3636 'mysql.pass' => '',
3737-3737+3838 // The MySQL server to connect to.
3939 'mysql.host' => 'localhost',
4040···56565757 // Is Recaptcha enabled? If disabled, captchas will not appear.
5858 'recaptcha.enabled' => false,
5959-5959+6060 // Your Recaptcha public key, obtained from Recaptcha.
6161 'recaptcha.public-key' => null,
6262-6262+6363 // Your Recaptcha private key, obtained from Recaptcha.
6464 'recaptcha.private-key' => null,
656566666767 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef',
6868-6868+6969 // When email is sent, try to hand it off to the MTA immediately. The only
7070 // reason to disable this is if your MTA infrastructure is completely
7171 // terrible. If you disable this option, you must run the 'metamta_mta.php'
7272 // daemon or mail won't be handed off to the MTA.
7373 'metamta.send-immediately' => true,
7474-7474+757576767777);
+17-1
scripts/daemons/metamta/metamta_mta.php
···11<?php
2233-// Placeholder so I don't forget about this, hopefully.33+/*
44+ * Copyright 2011 Facebook, Inc.
55+ *
66+ * Licensed under the Apache License, Version 2.0 (the "License");
77+ * you may not use this file except in compliance with the License.
88+ * You may obtain a copy of the License at
99+ *
1010+ * http://www.apache.org/licenses/LICENSE-2.0
1111+ *
1212+ * Unless required by applicable law or agreed to in writing, software
1313+ * distributed under the License is distributed on an "AS IS" BASIS,
1414+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515+ * See the License for the specific language governing permissions and
1616+ * limitations under the License.
1717+ */
1818+1919+// Placeholder so I don't forget about this, hopefully.
···11+<?php
22+33+/*
44+ * Copyright 2011 Facebook, Inc.
55+ *
66+ * Licensed under the Apache License, Version 2.0 (the "License");
77+ * you may not use this file except in compliance with the License.
88+ * You may obtain a copy of the License at
99+ *
1010+ * http://www.apache.org/licenses/LICENSE-2.0
1111+ *
1212+ * Unless required by applicable law or agreed to in writing, software
1313+ * distributed under the License is distributed on an "AS IS" BASIS,
1414+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515+ * See the License for the specific language governing permissions and
1616+ * limitations under the License.
1717+ */
1818+1919+class DifferentialInlineComment extends DifferentialDAO {
2020+2121+ protected $revisionID;
2222+ protected $commentID;
2323+ protected $authorPHID;
2424+2525+ protected $changesetID;
2626+ protected $isNewFile;
2727+2828+ protected $lineNumber;
2929+ protected $lineLength;
3030+3131+ protected $content;
3232+3333+}
···11+<?php
22+/**
33+ * This file is automatically generated. Lint this module to rebuild it.
44+ * @generated
55+ */
66+77+88+99+phutil_require_module('phabricator', 'applications/differential/storage/base');
1010+1111+1212+phutil_require_source('DifferentialInlineComment.php');
···824824 * }
825825 * });
826826 *
827827- *
828827 * @return string|null ##null## if there is no associated special key,
829828 * or one of the strings 'delete', 'tab', 'return',
830829 * 'esc', 'left', 'up', 'right', or 'down'.
···836835 return null;
837836 }
838837839839- var c = r.keyCode;
840840- do {
841841- c = JX.Event._keymap[c] || null;
842842- } while (c && JX.Event._keymap[c])
843843-844844- return c;
838838+ return JX.Event._keymap[r.keyCode] || null;
845839 },
840840+846841847842 /**
848843 * Get the node corresponding to the specified key in this event's node map.
···850845 * less ugly.
851846 *
852847 * JX.Stratcom.listen('click', 'tag:a', function(e) {
853853- * var a = e.getNode('nearest:a');
848848+ * var a = e.getNode('tag:a');
854849 * // do something with the link that was clicked
855850 * });
856851 *
···862857 * - sigil - first node of each sigil
863858 * @task info
864859 */
865865- getNode: function(key) {
860860+ getNode : function(key) {
866861 return this.getNodes()[key] || null;
862862+ },
863863+864864+865865+ /**
866866+ * Get the metadata associated with the node that corresponds to the key
867867+ * in this event's node map. This is a simple helper method that makes
868868+ * the API for accessing metadata associated with specific nodes less ugly.
869869+ *
870870+ * JX.Stratcom.listen('click', 'tag:a', function(event) {
871871+ * var anchorData = event.getNodeData('tag:a');
872872+ * // do something with the metadata of the link that was clicked
873873+ * });
874874+ *
875875+ * @param string sigil or stratcom node key
876876+ * @return dict dictionary of the node's metadata
877877+ * @task info
878878+ */
879879+ getNodeData : function(key) {
880880+ // Evade static analysis - JX.Stratcom
881881+ return JX['Stratcom'].getData(this.getNode(key));
867882 }
868868-869883 },
870884871885 statics : {
···878892 38 : 'up',
879893 39 : 'right',
880894 40 : 'down',
881881- 63232 : 38,
882882- 63233 : 40,
883883- 62234 : 37,
884884- 62235 : 39
895895+ 63232 : 'up',
896896+ 63233 : 'down',
897897+ 62234 : 'left',
898898+ 62235 : 'right'
885899 }
886900 },
887901···10081022 * @task listen Listening to Events
10091023 * @task handle Responding to Events
10101024 * @task sigil Managing Sigils
10251025+ * @task meta Managing Metadata
10111026 * @task internal Internals
10121027 */
10131028JX.install('Stratcom', {
···10161031 _targets : {},
10171032 _handlers : [],
10181033 _need : {},
10191019- _matchName : /\bFN_([^ ]+)/,
10201020- _matchData : /\bFD_([^ ]+)_([^ ]+)/,
10211034 _auto : '*',
10221035 _data : {},
10231036 _execContext : [],
···1039105210401053 /**
10411054 * Within each datablock, data is identified by a unique index. The data
10421042- * pointer on a node looks like this:
10551055+ * pointer (data-meta attribute) on a node looks like this:
10431056 *
10441044- * FD_1_2
10571057+ * 1_2
10451058 *
10461059 * ...where 1 is the block, and 2 is the index within that block. Normally,
10471060 * blocks are filled on the server side, so index allocation takes place
10481048- * there. However, when data is provided with JX.Stratcom.sigilize(), we
10611061+ * there. However, when data is provided with JX.Stratcom.addData(), we
10491062 * need to allocate indexes on the client.
10501063 */
10511064 _dataIndex : 0,
···11851198 if (path[kk] == 'tag:#document') {
11861199 throw new Error(
11871200 'JX.Stratcom.listen(..., "tag:#document", ...): ' +
11881188- 'listen for document events as "tag:window", not ' +
11891189- '"tag:#document", in order to get consistent behavior ' +
11901190- 'across browsers.');
12011201+ 'listen for all events using null, not "tag:#document"');
12021202+ }
12031203+ if (path[kk] == 'tag:window') {
12041204+ throw new Error(
12051205+ 'JX.Stratcom.listen(..., "tag:window", ...): ' +
12061206+ 'listen for window events using null, not "tag:window"');
11911207 }
11921208 }
11931209 if (!type_target[path[kk]]) {
···12191235 * @task internal
12201236 */
12211237 dispatch : function(event) {
12221222- // TODO: simplify this :P
12231223- var target;
12241224- try {
12251225- target = event.srcElement || event.target;
12261226- if (target === window || (!target || target.nodeName == '#document')) {
12271227- target = {nodeName: 'window'};
12281228- }
12291229- } catch (x) {
12301230- target = null;
12311231- }
12321232-12331238 var path = [];
12341239 var nodes = {};
12351240 var push = function(key, node) {
12361241 // we explicitly only store the first occurrence of each key
12371237- if (!(key in nodes)) {
12421242+ if (!nodes.hasOwnProperty(key)) {
12381243 nodes[key] = node;
12391244 path.push(key);
12401245 }
12411246 };
1242124712481248+ var target = event.srcElement || event.target;
12491249+12501250+ // Since you can only listen by tag, id or sigil, which are all
12511251+ // attributes of an Element (the DOM interface), we unset the target
12521252+ // if it isn't an Element (window and Document are Nodes but not Elements)
12531253+ if (!target || !target.getAttribute) {
12541254+ target = null;
12551255+ }
12561256+12431257 var cursor = target;
12441244- while (cursor) {
12581258+ while (cursor && cursor.getAttribute) {
12451259 push('tag:' + cursor.nodeName.toLowerCase(), cursor);
1246126012471261 var id = cursor.id;
···12491263 push('id:' + id, cursor);
12501264 }
1251126512521252- var source = cursor.className || '';
12531253- // className is an SVGAnimatedString for SVG elements, use baseVal
12541254- var token = ((source.baseVal || source).match(this._matchName) || [])[1];
12551255- if (token) {
12561256- push(token, cursor);
12661266+ var sigils = cursor.getAttribute('data-sigil');
12671267+ if (sigils) {
12681268+ sigils = sigils.split(' ');
12691269+ for (var ii = 0; ii < sigils.length; ii++) {
12701270+ push(sigils[ii], cursor);
12711271+ }
12571272 }
1258127312591274 cursor = cursor.parentNode;
···12641279 etype = this._typeMap[etype];
12651280 }
1266128112671267- var data = {};
12681268- for (var key in nodes) {
12691269- data[key] = this.getData(nodes[key]);
12701270- }
12711271-12721282 var proxy = new JX.Event()
12731283 .setRawEvent(event)
12741284 .setType(etype)
12751285 .setTarget(target)
12761276- .setData(data)
12771286 .setNodes(nodes)
12781287 .setPath(path.reverse());
12791288···140914181410141914111420 /**
14121412- * Attach a sigil (and, optionally, metadata) to a node. Note that you can
14131413- * not overwrite, remove or replace a sigil.
14211421+ * Determine if a node has a specific sigil.
14141422 *
14151415- * @param Node Node without any sigil.
14161416- * @param string Sigil to name the node with.
14171417- * @param object? Optional metadata object to attach to the node.
14181418- * @return void
14231423+ * @param Node Node to test.
14241424+ * @param string Sigil to check for.
14251425+ * @return bool True if the node has the sigil.
14261426+ *
14191427 * @task sigil
14201428 */
14211421- sigilize : function(node, sigil, data) {
14291429+ hasSigil : function(node, sigil) {
14221430 if (__DEV__) {
14231423- if (node.className.match(this._matchName)) {
14311431+ if (!node || !node.getAttribute) {
14241432 throw new Error(
14251425- 'JX.Stratcom.sigilize(<node>, ' + sigil + ', ...): ' +
14261426- 'node already has a sigil, sigils may not be overwritten.');
14271427- }
14281428- if (typeof data != 'undefined' &&
14291429- (data === null || typeof data != 'object')) {
14301430- throw new Error(
14311431- 'JX.Stratcom.sigilize(..., ..., <nonobject>): ' +
14321432- 'data to attach to node is not an object. You must use ' +
14331433- 'objects, not primitives, for metadata.');
14331433+ 'JX.Stratcom.hasSigil(<non-element>, ...): ' +
14341434+ 'node is not an element. Most likely, you\'re passing window or ' +
14351435+ 'document, which are not elements and can\'t have sigils.');
14341436 }
14351437 }
1436143814371437- if (data) {
14381438- JX.Stratcom._setData(node, data);
14391439- }
14401440-14411441- node.className = 'FN_' + sigil + ' ' + node.className;
14391439+ var sigils = node.getAttribute('data-sigil');
14401440+ return sigils && (' ' + sigils + ' ').indexOf(' ' + sigil + ' ') > -1;
14421441 },
144314421444144314451444 /**
14461446- * Determine if a node has a specific sigil.
14451445+ * Add a sigil to a node.
14471446 *
14481448- * @param Node Node to test.
14491449- * @param string Sigil to check for.
14501450- * @return bool True if the node has the sigil.
14511451- *
14471447+ * @param Node Node to add the sigil to.
14481448+ * @param string Sigil to name the node with.
14491449+ * @return void
14521450 * @task sigil
14531451 */
14541454- hasSigil : function(node, sigil) {
14551455- if (!node.className) {
14561456- // Some nodes don't have a className, notably 'document'. We hit
14571457- // 'document' when following .parentNode chains, e.g. in
14581458- // JX.DOM.nearest(), so exit early if we don't have a className to avoid
14591459- // fataling on 'node.className.match' being undefined.
14601460- return false;
14521452+ addSigil: function(node, sigil) {
14531453+ if (__DEV__) {
14541454+ if (!node || !node.getAttribute) {
14551455+ throw new Error(
14561456+ 'JX.Stratcom.addSigil(<non-element>, ...): ' +
14571457+ 'node is not an element. Most likely, you\'re passing window or ' +
14581458+ 'document, which are not elements and can\'t have sigils.');
14591459+ }
14601460+ }
14611461+14621462+ var sigils = node.getAttribute('data-sigil');
14631463+ if (sigils && !JX.Stratcom.hasSigil(node, sigil)) {
14641464+ sigil = sigils + ' ' + sigil;
14611465 }
14621462- return (node.className.match(this._matchName) || [])[1] == sigil;
14661466+14671467+ node.setAttribute('data-sigil', sigil);
14631468 },
146414691465147014661471 /**
14671472 * Retrieve a node's metadata.
14681473 *
14691469- * @param Node Node from which to retrieve data.
14701470- * @return object Data attached to the node, or an empty dictionary if
14711471- * the node has no data attached. In this case, the empty
14721472- * dictionary is set as the node's metadata -- i.e.,
14731473- * subsequent calls to getData() will retrieve the same
14741474- * object.
14751475- *
14761476- * @task sigil
14741474+ * @param Node Node from which to retrieve data.
14751475+ * @return object Data attached to the node. If no data has been attached
14761476+ * to the node yet, an empty object will be returned, but
14771477+ * subsequent calls to this method will always retrieve the
14781478+ * same object.
14791479+ * @task meta
14771480 */
14781481 getData : function(node) {
14791482 if (__DEV__) {
14801480- if (!node) {
14831483+ if (!node || !node.getAttribute) {
14811484 throw new Error(
14821482- 'JX.Stratcom.getData(<empty>): ' +
14831483- 'you must provide a node to get associated data from.');
14851485+ 'JX.Stratcom.getData(<non-element>): ' +
14861486+ 'node is not an element. Most likely, you\'re passing window or ' +
14871487+ 'document, which are not elements and can\'t have data.');
14841488 }
14851489 }
1486149014871487- var matches = (node.className || '').match(this._matchData);
14881488- if (matches) {
14891489- var block = this._data[matches[1]];
14901490- var index = matches[2];
14911491+ var meta_id = (node.getAttribute('data-meta') || '').split('_');
14921492+ if (meta_id[0] && meta_id[1]) {
14931493+ var block = this._data[meta_id[0]];
14941494+ var index = meta_id[1];
14911495 if (block && (index in block)) {
14921496 return block[index];
14931497 }
14941498 }
1495149914961496- return JX.Stratcom._setData(node, {});
15001500+ var data = {};
15011501+ if (!this._data[1]) { // data block 1 is reserved for JavaScript
15021502+ this._data[1] = {};
15031503+ }
15041504+ this._data[1][this._dataIndex] = data;
15051505+ node.setAttribute('data-meta', '1_' + (this._dataIndex++));
15061506+ return data;
14971507 },
1498150815091509+14991510 /**
15001500-15011501- * @task internal
15111511+ * Add data to a node's metadata.
15121512+ *
15131513+ * @param Node Node which data should be attached to.
15141514+ * @param object Data to add to the node's metadata.
15151515+ * @return object Data attached to the node that is returned by
15161516+ * JX.Stratcom.getData().
15171517+ * @task meta
15021518 */
15031503- allocateMetadataBlock : function() {
15041504- return this._dataBlock++;
15191519+ addData : function(node, data) {
15201520+ if (__DEV__) {
15211521+ if (!node || !node.getAttribute) {
15221522+ throw new Error(
15231523+ 'JX.Stratcom.addData(<non-element>, ...): ' +
15241524+ 'node is not an element. Most likely, you\'re passing window or ' +
15251525+ 'document, which are not elements and can\'t have sigils.');
15261526+ }
15271527+ if (!data || typeof data != 'object') {
15281528+ throw new Error(
15291529+ 'JX.Stratcom.addData(..., <nonobject>): ' +
15301530+ 'data to attach to node is not an object. You must use ' +
15311531+ 'objects, not primitives, for metadata.');
15321532+ }
15331533+ }
15341534+15351535+ return JX.copy(JX.Stratcom.getData(node), data);
15051536 },
1506153715381538+15071539 /**
15081508- * Attach metadata to a node. This data can later be retrieved through
15091509- * @{JX.Stratcom.getData()}, or @{JX.Event.getData()}.
15101510- *
15111511- * @param Node Node which data should be attached to.
15121512- * @param object Data to attach.
15131513- * @return object Attached data.
15141514- *
15151540 * @task internal
15161541 */
15171517- _setData : function(node, data) {
15181518- if (!this._data[1]) { // data block 1 is reserved for javascript
15191519- this._data[1] = {};
15201520- }
15211521- this._data[1][this._dataIndex] = data;
15221522- node.className = 'FD_1_' + (this._dataIndex++) + ' ' + node.className;
15231523- return data;
15421542+ allocateMetadataBlock : function() {
15431543+ return this._dataBlock++;
15241544 }
15251545 }
15261546});
···1535155515361556JX.behavior = function(name, control_function) {
15371557 if (__DEV__) {
15381538- if (name in JX.behavior._behaviors) {
15581558+ if (JX.behavior._behaviors.hasOwnProperty(name)) {
15391559 throw new Error(
15401560 'JX.behavior("'+name+'", ...): '+
15411561 'behavior is already registered.');
···15661586 }
15671587 var configs = map[name];
15681588 if (!configs.length) {
15691569- if (name in JX.behavior._initialized) {
15891589+ if (JX.behavior._initialized.hasOwnProperty(name)) {
15701590 continue;
15711591 } else {
15721592 configs = [null];
···18271847 },
1828184818291849 initialize : function() {
18301830- JX.Stratcom.listen('unload', 'tag:window', JX.Request.shutdown);
18501850+ JX.Stratcom.listen('unload', null, JX.Request.shutdown);
18311851 }
1832185218331853});
···24102430 }
2411243124122432 if (attr.sigil) {
24132413- JX.Stratcom.sigilize(node, attr.sigil, attr.meta);
24332433+ JX.Stratcom.addSigil(node, attr.sigil);
24142434 delete attr.sigil;
24352435+ }
24362436+24372437+ if (attr.meta) {
24382438+ JX.Stratcom.addData(node, attr.meta);
24152439 delete attr.meta;
24162440 }
24172441···24212445 '$N(' + tag + ', ...): ' +
24222446 'use the key "meta" to specify metadata, not "data" or "metadata".');
24232447 }
24242424- if (attr.meta) {
24252425- throw new Error(
24262426- '$N(' + tag + ', ...): ' +
24272427- 'if you specify "meta" metadata, you must also specify a "sigil".');
24282428- }
24292429- }
24302430-24312431- // prevent sigil from being wiped by blind copying the className
24322432- if (attr.className) {
24332433- JX.DOM.alterClass(node, attr.className, true);
24342434- delete attr.className;
24352448 }
2436244924372450 JX.copy(node, attr);
···25952608 * @author jgabbard
25962609 */
25972610 nearest : function(node, sigil) {
25982598- while (node && !JX.Stratcom.hasSigil(node, sigil)) {
26112611+ while (node && node.getAttribute && !JX.Stratcom.hasSigil(node, sigil)) {
25992612 node = node.parentNode;
26002613 }
26012614 return node;