@@ -104,11 +104,7 @@ bool MCClipboard::IsLocked() const
104104void MCClipboard::Clear ()
105105{
106106 // Clear the private data
107- if (m_private_data != NULL )
108- {
109- MCValueRelease (m_private_data);
110- m_private_data = NULL ;
111- }
107+ ClearPrivateData ();
112108
113109 // Pass on the request
114110 Lock ();
@@ -126,7 +122,11 @@ void MCClipboard::ReleaseData()
126122
127123bool MCClipboard::PullUpdates () const
128124{
129- // Pass on the request
125+ // If ownership has changed, the private clipboard data needs to be cleared
126+ if (!m_clipboard->IsOwned ())
127+ const_cast <MCClipboard*>(this )->ClearPrivateData ();
128+
129+ // Pass on the request
130130 return m_clipboard->PullUpdates ();
131131}
132132
@@ -371,14 +371,21 @@ bool MCClipboard::AddLiveCodeStyledText(MCDataRef p_pickled_text)
371371 if (t_success && (t_type_string = m_clipboard->GetKnownTypeString (kMCRawClipboardKnownTypeHTML )) != NULL )
372372 {
373373 // This type is optional as it may not be a faithful representation
374- MCAutoDataRef t_html (ConvertStyledTextToHTML (p_pickled_text));
374+ MCAutoStringRef t_html (ConvertStyledTextToHTML (p_pickled_text));
375375 if (*t_html != NULL )
376376 {
377- MCAutoDataRef t_encoded;
378- t_encoded = m_clipboard->EncodeHTMLFragmentForTransfer (*t_html);
379- t_success = *t_encoded != nil;
377+ // All platforms accept UTF-8 as an encoding for HTML on the clipboard
378+ MCAutoDataRef t_html_utf8;
379+ t_success = MCStringEncode (*t_html, kMCStringEncodingUTF8 , false , &t_html_utf8);
380+
380381 if (t_success)
381- t_success = t_item->AddRepresentation (t_type_string, *t_encoded);
382+ {
383+ MCAutoDataRef t_encoded;
384+ t_encoded = m_clipboard->EncodeHTMLFragmentForTransfer (*t_html_utf8);
385+ t_success = *t_encoded != nil;
386+ if (t_success)
387+ t_success = t_item->AddRepresentation (t_type_string, *t_encoded);
388+ }
382389 }
383390 }
384391
@@ -404,14 +411,14 @@ bool MCClipboard::AddLiveCodeStyledTextArray(MCArrayRef p_styled_text)
404411 return AddLiveCodeStyledText (*t_pickled_text);
405412}
406413
407- bool MCClipboard::AddHTMLText (MCDataRef p_html_data )
414+ bool MCClipboard::AddHTMLText (MCStringRef p_html_string )
408415{
409416 // Adding HTML to the clipboard is done by converting the HTML to LiveCode's
410417 // internal styled-text format and then adding it to the clipboard in that
411418 // format.
412419 //
413420 // This is a lossy process but preserves legacy behaviour.
414- MCAutoDataRef t_pickled_text (ConvertHTMLToStyledText (p_html_data ));
421+ MCAutoDataRef t_pickled_text (ConvertHTMLToStyledText (p_html_string ));
415422 if (*t_pickled_text == NULL )
416423 return false ;
417424
@@ -425,7 +432,7 @@ bool MCClipboard::AddRTFText(MCDataRef p_rtf_data)
425432 // format.
426433 //
427434 // This is a lossy process but preserves legacy behaviour.
428- MCAutoDataRef t_pickled_text (ConvertHTMLToStyledText (p_rtf_data));
435+ MCAutoDataRef t_pickled_text (ConvertRTFToStyledText (p_rtf_data));
429436 if (*t_pickled_text == NULL )
430437 return false ;
431438
@@ -453,10 +460,15 @@ bool MCClipboard::AddRTF(MCDataRef p_rtf)
453460 return t_item->AddRepresentation (t_type_string, p_rtf);
454461}
455462
456- bool MCClipboard::AddHTML (MCDataRef p_html)
463+ bool MCClipboard::AddHTML (MCStringRef p_html)
457464{
458465 AutoLock t_lock (this );
459466
467+ // All platforms support UTF-8 as a text encoding for HTML on the clipboard
468+ MCAutoDataRef t_html_utf8;
469+ if (!MCStringEncode (p_html, kMCStringEncodingUTF8 , false , &t_html_utf8))
470+ return false ;
471+
460472 // Clear the contents if the clipboard contains external data
461473 if (m_clipboard->IsExternalData ())
462474 Clear ();
@@ -465,10 +477,10 @@ bool MCClipboard::AddHTML(MCDataRef p_html)
465477 MCAutoRefcounted<MCRawClipboardItem> t_item = GetItem ();
466478 if (t_item == NULL )
467479 return false ;
468-
480+
469481 // Encode the HTML in the required format for the clipboard
470482 MCAutoDataRef t_encoded;
471- t_encoded = m_clipboard->EncodeHTMLFragmentForTransfer (p_html );
483+ t_encoded = m_clipboard->EncodeHTMLFragmentForTransfer (*t_html_utf8 );
472484 if (*t_encoded == nil)
473485 return false ;
474486
@@ -477,7 +489,7 @@ bool MCClipboard::AddHTML(MCDataRef p_html)
477489 if (t_type_string == NULL )
478490 return false ;
479491
480- return t_item->AddRepresentation (t_type_string, p_html );
492+ return t_item->AddRepresentation (t_type_string, *t_encoded );
481493}
482494
483495bool MCClipboard::AddPNG (MCDataRef p_png)
@@ -966,21 +978,15 @@ bool MCClipboard::CopyAsLiveCodeStyledText(MCDataRef& r_pickled_text) const
966978 }
967979
968980 // Could not grab as either styled text or RTF. Try with HTML.
969- MCAutoDataRef t_html;
970- if (CopyAsData ( kMCRawClipboardKnownTypeHTML , &t_html))
981+ MCAutoStringRef t_html;
982+ if (CopyAsHTML ( &t_html))
971983 {
972- MCAutoDataRef t_decodedhtml;
973- t_decodedhtml.Reset (m_clipboard->DecodeTransferredHTML (*t_html));
974-
975- if (*t_decodedhtml != nil)
984+ // Convert to LiveCode styled text
985+ MCDataRef t_pickled_text = ConvertHTMLToStyledText (*t_html);
986+ if (t_pickled_text != NULL )
976987 {
977- // Convert to LiveCode styled text
978- MCDataRef t_pickled_text = ConvertHTMLToStyledText (*t_decodedhtml);
979- if (t_pickled_text != NULL )
980- {
981- r_pickled_text = t_pickled_text;
982- return true ;
983- }
988+ r_pickled_text = t_pickled_text;
989+ return true ;
984990 }
985991 }
986992
@@ -1036,7 +1042,7 @@ bool MCClipboard::CopyAsRTFText(MCDataRef& r_rtf) const
10361042 return true ;
10371043}
10381044
1039- bool MCClipboard::CopyAsHTMLText (MCDataRef & r_html) const
1045+ bool MCClipboard::CopyAsHTMLText (MCStringRef & r_html) const
10401046{
10411047 AutoLock t_lock (this );
10421048
@@ -1046,11 +1052,12 @@ bool MCClipboard::CopyAsHTMLText(MCDataRef& r_html) const
10461052 if (!CopyAsLiveCodeStyledText (&t_pickled_text))
10471053 return false ;
10481054
1049- MCDataRef t_html = ConvertStyledTextToHTML (*t_pickled_text);
1050- if (t_html == NULL )
1055+ MCAutoStringRef t_html;
1056+ t_html.Give (ConvertStyledTextToHTML (*t_pickled_text));
1057+ if (*t_html == nil)
10511058 return false ;
10521059
1053- r_html = t_html;
1060+ r_html = t_html. Take () ;
10541061 return true ;
10551062}
10561063
@@ -1059,18 +1066,24 @@ bool MCClipboard::CopyAsRTF(MCDataRef& r_rtf_data) const
10591066 return CopyAsData (kMCRawClipboardKnownTypeRTF , r_rtf_data);
10601067}
10611068
1062- bool MCClipboard::CopyAsHTML (MCDataRef& r_html_data ) const
1069+ bool MCClipboard::CopyAsHTML (MCStringRef& r_html ) const
10631070{
10641071 MCAutoDataRef t_data;
10651072 if (!CopyAsData (kMCRawClipboardKnownTypeHTML , &t_data))
10661073 return false ;
10671074
1068- MCDataRef t_decoded = nil;
1069- t_decoded = m_clipboard->DecodeTransferredHTML (*t_data);
1070- if (t_decoded == nil)
1075+ MCAutoDataRef t_decoded;
1076+ t_decoded.Give (m_clipboard->DecodeTransferredHTML (*t_data));
1077+ if (*t_decoded == nil)
1078+ return false ;
1079+
1080+ // Convert the decoded HTML data into a string
1081+ MCStringEncoding t_encoding = GuessHTMLEncoding (*t_decoded);
1082+ MCAutoStringRef t_html_string;
1083+ if (!MCStringDecode (*t_decoded, t_encoding, false , &t_html_string))
10711084 return false ;
10721085
1073- r_html_data = t_decoded ;
1086+ r_html = t_html_string. Take () ;
10741087 return true ;
10751088}
10761089
@@ -1145,6 +1158,14 @@ bool MCClipboard::CopyAsPrivateData(MCDataRef& r_data) const
11451158 return true ;
11461159}
11471160
1161+ void MCClipboard::ClearPrivateData ()
1162+ {
1163+ if (m_private_data)
1164+ MCValueRelease (m_private_data);
1165+
1166+ m_private_data = nil;
1167+ }
1168+
11481169// Wrapper for MCStringIsEqualTo that handles NULL parameters
11491170static bool MCTypeMatches (MCStringRef p_one, MCStringRef p_two)
11501171{
@@ -1286,7 +1307,7 @@ MCStringRef MCClipboard::ConvertStyledTextToText(MCDataRef p_pickled_text)
12861307 return MCValueRetain (*t_text);
12871308}
12881309
1289- MCDataRef MCClipboard::ConvertStyledTextToHTML (MCDataRef p_pickled_text)
1310+ MCStringRef MCClipboard::ConvertStyledTextToHTML (MCDataRef p_pickled_text)
12901311{
12911312 // Turn the pickled text into a StyledText object
12921313 MCObject *t_object = MCObject::unpickle (p_pickled_text, MCtemplatefield -> getstack ());
@@ -1305,8 +1326,14 @@ MCDataRef MCClipboard::ConvertStyledTextToHTML(MCDataRef p_pickled_text)
13051326 delete t_object;
13061327 if (!t_success)
13071328 return NULL ;
1308-
1309- return MCValueRetain (*t_html);
1329+
1330+ // Convert the HTML into a string
1331+ // exportashtmltext always returns native-encoded data (where non-ASCII chars are entity-encoded)
1332+ MCAutoStringRef t_html_string;
1333+ if (!MCStringDecode (*t_html, kMCStringEncodingNative , false , &t_html_string))
1334+ return nil;
1335+
1336+ return t_html_string.Take ();
13101337}
13111338
13121339MCDataRef MCClipboard::ConvertStyledTextToRTF (MCDataRef p_pickled_text)
@@ -1365,10 +1392,10 @@ MCDataRef MCClipboard::ConvertRTFToStyledText(MCDataRef p_rtf_data)
13651392 return t_pickled_text;
13661393}
13671394
1368- MCDataRef MCClipboard::ConvertHTMLToStyledText (MCDataRef p_html_data )
1395+ MCDataRef MCClipboard::ConvertHTMLToStyledText (MCStringRef p_html_string )
13691396{
13701397 // Turn the HTML into paragraphs
1371- MCParagraph *t_paragraphs = MCtemplatefield->importhtmltext (p_html_data );
1398+ MCParagraph *t_paragraphs = MCtemplatefield->importhtmltext (p_html_string );
13721399 if (t_paragraphs == NULL )
13731400 return NULL ;
13741401
@@ -1510,3 +1537,16 @@ MCClipboard* MCClipboard::CreateSystemDragboard()
15101537 t_dragboard->Clear ();
15111538 return t_dragboard;
15121539}
1540+
1541+ MCStringEncoding MCClipboard::GuessHTMLEncoding (MCDataRef p_html_data)
1542+ {
1543+ // All of our platforms (seem to) use UTF-8 as the text encoding for HTML
1544+ // data transferred via the clipboard. Windows guarantees this; for Mac and
1545+ // Linux the situation is unclear (but various places in the engine seem to
1546+ // assume this anyway).
1547+ //
1548+ // If it turns out that non-UTF-8 HTML gets passed via the clipboard, this
1549+ // function should be updated to detect it if possible.
1550+
1551+ return kMCStringEncodingUTF8 ;
1552+ }
0 commit comments