Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | /chat: do not show the Toggle Text Mode feature for messages with no text, e.g. image-only posts (resolves an unhandled exception). When text is toggled to the unparsed state, show a copy-to-clipboard button which copies the raw message text to the clipboard. That is a workaround for mouse-copying of that text collecting extraneous newlines for reasons only the browsers understand. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
f98a4f5c94a844dd270526f380d8f6aa |
| User & Date: | stephan 2022-06-08 15:52:08.791 |
References
|
2022-06-20
| ||
| 22:18 | /chat: added a missing JS dependency which broke the new text-toggle/copy feature. Bug introduced in [f98a4f5c94a844dd], caused by failure to check in one of the associated files. ... (check-in: eeacf82158 user: stephan tags: trunk) | |
Context
|
2022-06-08
| ||
| 23:27 | Merge in pikchrshow-wasm branch: reimplement /pikchrshow using a client-side WASM build of pikchr.c, plus related feature-adjacent tweaks in mimetype handling. ... (check-in: 7fcb462680 user: stephan tags: trunk) | |
| 15:52 | /chat: do not show the Toggle Text Mode feature for messages with no text, e.g. image-only posts (resolves an unhandled exception). When text is toggled to the unparsed state, show a copy-to-clipboard button which copies the raw message text to the clipboard. That is a workaround for mouse-copying of that text collecting extraneous newlines for reasons only the browsers understand. ... (check-in: f98a4f5c94 user: stephan tags: trunk) | |
| 15:17 | In /chat, change the EOL whitespace-stripping policy to retain up to 2 spaces, only stripping after the 3rd, to avoid breaking certain markdown constructs. Per /chat discussion. ... (check-in: cd7f2ddc98 user: stephan tags: trunk) | |
Changes
Changes to src/fossil.copybutton.js.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 |
Options:
.copyFromElement: DOM element
.copyFromId: DOM element ID
| < < < > > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
Options:
.copyFromElement: DOM element
.copyFromId: DOM element ID
.extractText: optional callback which is triggered when the copy
button is clicked. It must return the text to copy to the
clipboard. The default is to extract it from the copy-from
element, using its [value] member, if it has one, else its
[innerText]. A client-provided callback may use any data source
it likes, so long as it's synchronous. If this function returns a
falsy value then the clipboard is not modified. This function is
called with the fully expanded/resolved options object as its
"this" (that's a different instance than the one passed to this
function!).
At least one of copyFromElement, copyFromId, or extractText must
be provided, but if copyFromId is not set and e.dataset.copyFromId
is then that value is used in its place. extractText() trumps the
other two options.
.cssClass: optional CSS class, or list of classes, to apply to e.
.style: optional object of properties to copy directly into
e.style.
.oncopy: an optional callback function which is added as an event
|
| ︙ | ︙ |
Changes to src/fossil.page.chat.js.
| ︙ | ︙ | |||
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
}else{
e = this.getMessageElemById(id);
}
if(!e || !id) return false;
else if(e.$isToggling) return;
e.$isToggling = true;
const content = e.querySelector('.content-target');
if(!content.$elems){
content.$elems = [
content.firstElementChild, // parsed elem
undefined // plaintext elem
];
}else if(content.$elems[1]){
// We have both content types. Simply toggle them.
const child = (
content.firstElementChild===content.$elems[0]
? content.$elems[1]
: content.$elems[0]
);
delete e.$isToggling;
| > > > > > > > > > > > > > > > > > > > > > > | > | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
}else{
e = this.getMessageElemById(id);
}
if(!e || !id) return false;
else if(e.$isToggling) return;
e.$isToggling = true;
const content = e.querySelector('.content-target');
if(!content){
console.warn("Should not be possible: trying to toggle text",
"mode of a message with no .content-target.", e);
return;
}
if(!content.$elems){
content.$elems = [
content.firstElementChild, // parsed elem
undefined // plaintext elem
];
}else if(content.$elems[1]){
// We have both content types. Simply toggle them.
const child = (
content.firstElementChild===content.$elems[0]
? content.$elems[1]
: content.$elems[0]
);
D.clearElement(content);
if(child===content.$elems[1]){
/* When showing the unformatted version, inject a
copy-to-clipboard button. This is a workaround for
mouse-copying from that field collecting twice as many
newlines as it should (for unknown reasons). */
const cpId = 'copy-to-clipboard-'+id;
/* ^^^ copy button element ID, needed for LABEL element
pairing. Recall that we destroy all child elements of
`content` each time we hit this block, so we can reuse
that element ID on subsequent toggles. */
const btnCp = D.attr(D.addClass(D.span(),'copy-button'), 'id', cpId);
F.copyButton(btnCp, {extractText: ()=>child._xmsgRaw});
const lblCp = D.label(cpId, "Copy unformatted text");
lblCp.addEventListener('click',()=>btnCp.click(), false);
D.append(content, D.append(D.addClass(D.span(), 'nobr'), btnCp, lblCp));
}
delete e.$isToggling;
D.append(content, child);
return;
}
// We need to fetch the plain-text version...
const self = this;
F.fetch('chat-fetch-one',{
urlParams:{ name: id, raw: true},
responseType: 'json',
onload: function(msg){
content.$elems[1] = D.append(D.pre(),msg.xmsg);
content.$elems[1]._xmsgRaw = msg.xmsg/*used for copy-to-clipboard feature*/;
self.toggleTextMode(e);
},
aftersend:function(){
delete e.$isToggling;
Chat.ajaxEnd();
}
});
|
| ︙ | ︙ | |||
1133 1134 1135 1136 1137 1138 1139 |
e = n;
}
eMsg.scrollIntoView();
}
));
const toolbar2 = D.addClass(D.div(), 'toolbar');
D.append(this.e, toolbar2);
| > > > | | | | | > | 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 |
e = n;
}
eMsg.scrollIntoView();
}
));
const toolbar2 = D.addClass(D.div(), 'toolbar');
D.append(this.e, toolbar2);
if(eMsg.querySelector('.content-target')){
/* ^^^ messages with only an embedded image have no
.content-target area. */
D.append(toolbar2, D.button(
"Toggle text mode", function(){
self.hide();
Chat.toggleTextMode(eMsg);
}));
}
if(eMsg.dataset.xfrom){
/* Add a link to the /timeline filtered on this user. */
const timelineLink = D.attr(
D.a(F.repoUrl('timeline',{
u: eMsg.dataset.xfrom,
y: 'a'
}), "User's Timeline"),
|
| ︙ | ︙ |