2011-03-22 20:41:02 -07:00
|
|
|
<?php
|
|
|
|
|
2012-03-13 16:21:04 -07:00
|
|
|
final class AphrontTokenizerTemplateView extends AphrontView {
|
2011-03-22 20:41:02 -07:00
|
|
|
|
|
|
|
private $value;
|
|
|
|
private $name;
|
|
|
|
private $id;
|
2015-04-16 13:37:12 -07:00
|
|
|
private $browseURI;
|
2015-12-15 06:57:32 -08:00
|
|
|
private $initialValue;
|
2015-04-16 13:37:12 -07:00
|
|
|
|
|
|
|
public function setBrowseURI($browse_uri) {
|
|
|
|
$this->browseURI = $browse_uri;
|
|
|
|
return $this;
|
|
|
|
}
|
2011-03-22 20:41:02 -07:00
|
|
|
|
|
|
|
public function setID($id) {
|
|
|
|
$this->id = $id;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setValue(array $value) {
|
2015-04-16 15:30:41 -07:00
|
|
|
assert_instances_of($value, 'PhabricatorTypeaheadTokenView');
|
2011-03-22 20:41:02 -07:00
|
|
|
$this->value = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getValue() {
|
|
|
|
return $this->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setName($name) {
|
|
|
|
$this->name = $name;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getName() {
|
|
|
|
return $this->name;
|
|
|
|
}
|
|
|
|
|
2015-12-15 06:57:32 -08:00
|
|
|
public function setInitialValue(array $initial_value) {
|
|
|
|
$this->initialValue = $initial_value;
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-12-15 06:57:32 -08:00
|
|
|
public function getInitialValue() {
|
|
|
|
return $this->initialValue;
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
}
|
|
|
|
|
2011-03-22 20:41:02 -07:00
|
|
|
public function render() {
|
|
|
|
require_celerity_resource('aphront-tokenizer-control-css');
|
|
|
|
|
|
|
|
$id = $this->id;
|
|
|
|
$name = $this->getName();
|
2015-04-16 15:30:41 -07:00
|
|
|
$tokens = nonempty($this->getValue(), array());
|
2011-03-22 20:41:02 -07:00
|
|
|
|
2013-01-25 12:57:17 -08:00
|
|
|
$input = javelin_tag(
|
2011-03-22 20:41:02 -07:00
|
|
|
'input',
|
|
|
|
array(
|
|
|
|
'mustcapture' => true,
|
|
|
|
'name' => $name,
|
|
|
|
'class' => 'jx-tokenizer-input',
|
Bring Javelin into Phabricator via git submodule, not copy-and-paste
Summary:
Javelin is currently embedded in Phabricator via copy-and-paste of prebuilt
packages. This is not so great.
Pull it in as a submodule instead and make all the Phabriator resources declare
proper dependency trees. Add Javelin linting.
Test Plan:
I tried to run through pretty much all the JS functionality on the site. This is
still a high-risk change, but I did a pretty thorough test
Differential: inline comments, revealing diffs, list tokenizers, comment
preview, editing/deleting comments, add review action.
Maniphest: list tokenizer, comment actions
Herald: rule editing, tokenizers, add/remove rows
Reviewed By: tomo
Reviewers: aran, tomo, mroch, jungejason, tuomaspelkonen
CC: aran, tomo, epriestley
Differential Revision: 223
2011-05-03 15:11:55 -07:00
|
|
|
'sigil' => 'tokenizer-input',
|
2011-03-22 20:41:02 -07:00
|
|
|
'style' => 'width: 0px;',
|
|
|
|
'disabled' => 'disabled',
|
|
|
|
'type' => 'text',
|
|
|
|
));
|
|
|
|
|
2013-01-18 00:32:58 -08:00
|
|
|
$content = $tokens;
|
|
|
|
$content[] = $input;
|
|
|
|
$content[] = phutil_tag('div', array('style' => 'clear: both;'), '');
|
|
|
|
|
2015-04-16 14:46:10 -07:00
|
|
|
$container = javelin_tag(
|
2011-03-22 20:41:02 -07:00
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'id' => $id,
|
|
|
|
'class' => 'jx-tokenizer-container',
|
2015-04-16 14:46:10 -07:00
|
|
|
'sigil' => 'tokenizer-container',
|
2011-03-22 20:41:02 -07:00
|
|
|
),
|
2013-01-18 00:32:58 -08:00
|
|
|
$content);
|
2015-04-16 13:37:12 -07:00
|
|
|
|
2015-04-16 14:46:10 -07:00
|
|
|
$icon = id(new PHUIIconView())
|
2015-04-18 10:58:50 -07:00
|
|
|
->setIconFont('fa-search');
|
2015-04-16 14:46:10 -07:00
|
|
|
|
|
|
|
$browse = id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setIcon($icon)
|
2015-04-18 10:58:50 -07:00
|
|
|
->addClass('tokenizer-browse-button')
|
2015-04-16 14:46:10 -07:00
|
|
|
->setColor(PHUIButtonView::GREY)
|
2015-04-18 10:58:50 -07:00
|
|
|
->addSigil('tokenizer-browse');
|
2015-04-16 14:46:10 -07:00
|
|
|
|
|
|
|
$classes = array();
|
|
|
|
$classes[] = 'jx-tokenizer-frame';
|
|
|
|
|
2015-04-16 13:37:12 -07:00
|
|
|
if ($this->browseURI) {
|
2015-04-16 14:46:10 -07:00
|
|
|
$classes[] = 'has-browse';
|
2015-04-16 13:37:12 -07:00
|
|
|
}
|
|
|
|
|
2015-12-15 06:57:32 -08:00
|
|
|
$initial = array();
|
|
|
|
$initial_value = $this->getInitialValue();
|
|
|
|
if ($initial_value) {
|
|
|
|
foreach ($this->getInitialValue() as $value) {
|
|
|
|
$initial[] = phutil_tag(
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
'input',
|
|
|
|
array(
|
|
|
|
'type' => 'hidden',
|
2015-12-15 06:57:32 -08:00
|
|
|
'name' => $name.'.initial[]',
|
Implement a basic version of ApplicationEditor in Paste
Summary:
Ref T9132. Ref T4768. This is a rough v0 of ApplicationEditor, which replaces the edit workflow in Paste.
This mostly looks and works like ApplicationSearch, and is heavily modeled on it.
Roughly, we define a set of editable fields and the ApplicationEditor stuff builds everything else.
This has no functional changes, except:
- I removed "Fork Paste" since I don't think it's particularly useful now that pastes are editable. We could restore it if users miss it.
- Subscribers are now editable.
- Form field order is a little goofy (this will be fixed in a future diff).
- Subscribers and projects are now race-resistant.
The race-resistance works like this: instead of submitting just the new value ("subscribers=apple, dog") and doing a set operation ("set subscribers = apple, dog"), we submit the old and new values ("original=apple" + "new=apple, dog") then apply the user's changes as an add + remove ("add=dog", "remove=<none>"). This means that two users who do "Edit Paste" at around the same time and each add or remove a couple of subscribers won't overwrite each other, unless they actually add or remove the exact same subscribers (in which case their edits legitimately conflict). Previously, the last user to save would win, and whatever was in their field would overwrite the prior state, potentially losing the first user's edits.
Test Plan:
- Created pastes.
- Created pastes via API.
- Edited pastes.
- Edited every field.
- Opened a paste in two windows and did project/subscriber edits in each, saved in arbitrary order, had edits respected.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T4768, T9132
Differential Revision: https://secure.phabricator.com/D14390
2015-11-02 18:58:32 -08:00
|
|
|
'value' => $value,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-16 13:37:12 -07:00
|
|
|
$frame = javelin_tag(
|
2015-04-18 10:58:50 -07:00
|
|
|
'div',
|
2015-04-16 13:37:12 -07:00
|
|
|
array(
|
2015-04-16 14:46:10 -07:00
|
|
|
'class' => implode(' ', $classes),
|
2015-04-16 13:37:12 -07:00
|
|
|
'sigil' => 'tokenizer-frame',
|
|
|
|
),
|
2015-04-18 10:58:50 -07:00
|
|
|
array(
|
|
|
|
$container,
|
|
|
|
$browse,
|
2015-12-15 06:57:32 -08:00
|
|
|
$initial,
|
2015-04-18 10:58:50 -07:00
|
|
|
));
|
2015-04-16 13:37:12 -07:00
|
|
|
|
|
|
|
return $frame;
|
2011-03-22 20:41:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|