2016-07-29 64 views
13

Ich kopiere Rich Text von div mit contenteditable="true" und Einfügen in einen Medium Entwurf. Der größte Teil der Formatierung bleibt erhalten, aber aus irgendeinem Grund verstehe ich nicht, dass alle relativen Links in absolute umgewandelt werden. Ich weiß nicht, auf welchem ​​Schritt dies geschieht. Ich dachte sogar, Medium könnte "Paste" -Ereignisse hören. Dies wäre das Worst-Case-Szenario, weil ich kaum Kontrolle darüber hätte. Aber wenn ja, wie haben sie Zugriff auf die URL der Seite, als ich den Inhalt kopiert habe? In der Tat, nach der Überprüfung mit anderen Browsern, habe ich festgestellt, dass es Chrome ist und nicht Mittel. Auf Safari funktioniert es einwandfrei, auf Firefox funktioniert es überhaupt nicht (aber das ist ein Thema für eine andere Frage ...).Wie kann Chrome verhindern, dass relative Links beim Kopieren/Einfügen in absolute Links umgewandelt werden?

Um die Dinge klarer zu machen, versuche ich das Verhalten der footnotes plugin ich auf meinem Wordpress Blog zu verwenden, indem Sie ein Bookmarklet schreiben, das im Wesentlichen das gleiche tut.

Hier ist eine Demo-Seite, wo Sie Text mit einer Wiki-ähnlicher Syntax für die Inline-Referenzen und analysieren sie in der richtigen Fußnoten einfügen können:

https://rawgit.com/arielpontes/footnoter/master/index.html

In beiden Modi der Nutzung ([1] Kopieren/Einfügen auf der Demoseite oder [2] mit dem Bookmarklet), hat das resultierende HTML die richtigen relativen Links. Nach dem Einfügen in Chrome auf Medium werden sie jedoch absolut und zeigen auf rawgit.com und brechen die Funktionalität.

Wenn ich den Code von meinem lokalen Computer anstelle von rawgit.com ausführen, werden die Links jedoch in relativer Form nach dem Einfügen auch in Chrome beibehalten.

Was könnte möglicherweise passieren? Gibt es eine Möglichkeit, es zu beheben?

Antwort

2

TL; DR - Die eine, die für den eingefügten Inhalt verantwortlich ist das Programm, das es in der Zwischenablage legt.

Jedes Mal, wenn Sie etwas in die Zwischenablage, die Anwendung kopieren, die Kopie funktioniert kann es mehrere Datentypen setzen, so dass das Programm, das Sie paste in der Lage, die man verwenden, die am besten für sich funktioniert. Im Falle eines Browsers - wenn Sie einen Inhalt einer Webseite auswählen und in Ihre Zwischenablage kopieren - erstellt der Browser zwei Arten (html/plain und text/html), wenn Sie also diesen Inhalt in ein Programm einfügen, das HTML verarbeiten kann - die Daten werden Sie Einfügen wird HTML sein, aber wenn nicht - diese Daten werden nur Text sein.

Grundsätzlich haben Sie zwei Möglichkeiten:

  1. Aufschalten der Inhalt, den der Browser in der Zwischenablage gespeichert (auf diese Weise - unabhängig davon, wo der Inhalt eingefügt werden - es aussehen wird genau so, wie Sie wollen)
  2. Entführen Sie das Einfügen-Ereignis, holen Sie die Daten aus der Zwischenablage, ändern Sie sie wie Sie wollen und legen Sie sie selbst in den Editor.

$('#text').on('paste', function(e) { 
 
    if ($('input[name=paste-type]:checked').val() == 'special') { 
 
    e.preventDefault(); 
 
    if (window.getSelection) { 
 
     sel = window.getSelection(); 
 
     if (sel.rangeCount) { 
 
     range = sel.getRangeAt(0); 
 
     range.deleteContents(); 
 
     node = document.createElement("p"); 
 
     text = 'Replacement text only for the paste' 
 
     node.appendChild(document.createTextNode(text)) 
 
     range.insertNode(node); 
 
     } 
 
    } 
 
    } 
 
}); 
 
$(document).on('copy', function(e) { 
 
    if ($('input[name=copy-type]:checked').val() == 'special') { 
 
    e.preventDefault(); 
 
    if (window.getSelection) { 
 
     sel = window.getSelection(); 
 
     if (sel.rangeCount) { 
 
     range = sel.getRangeAt(0); 
 
     nodes = range.cloneContents().childNodes 
 
     content = '' 
 
     contentPlain = '' 
 
     for (var i = 0; i < nodes.length; i++) { 
 
      node = nodes[i]; 
 
      contentPlain += node.textContent 
 
      if (node.nodeType == 3) { 
 
      content += node.textContent 
 
      } else if (node.nodeType == 1) { 
 
      content += node.outerHTML 
 
      } 
 
     } 
 
     } 
 
    } else { 
 
     content = '<span style="color: red; background: yellow;">Replacement text only for the copy</span>'; 
 
    } 
 
    e.originalEvent.clipboardData.setData('text/html', content); 
 
    e.originalEvent.clipboardData.setData('text/plain', contentPlain); 
 
    } 
 
}); 
 
$('#btn1').click(function() { 
 
    $('#ta1').val($('#text').html()); 
 
});
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script> 
 
<div id="text" contenteditable="true" style="width: 400px; height :250px; border: 1px solid black;">Paste your text here...</div><br /> 
 
<textarea id="ta1" style="width: 400px; height: 150px; border: 1px solid green;" disabled="disabled"></textarea><br /> 
 
<button id="btn1">View HTML</button><br /> 
 
<label for="reg"><input type="radio" name="paste-type" value="regular" id="reg" checked="checked" /> Regular Paste</label> 
 
<label for="special"><input type="radio" name="paste-type" value="special" id="special" /> Force my paste</label> 
 
<br /><br /> 
 
<label for="copy-reg"><input type="radio" name="copy-type" value="regular" id="copy-reg" checked="checked" /> Regular Copy</label> 
 
<label for="copy-special"><input type="radio" name="copy-type" value="special" id="copy-special" /> Force my copy</label> 
 
<br /><br /> 
 
<div style="width: 400px; height: 300px; border: 1px solid red;"> 
 
    <p>Nonumes molestiae <b>scripserit mei eu. In sea singulis evertitur</b>, verear inimicus delicatissimi ad eam. Eu eros scripserit cum, nam ferri ludus saperet te, ex sea nostro prompta inciderint. Est at causae .</p> 
 
    <p>Quem feugait nam cu, sed <span style="background: red;">tantas meliore eu. Propriae efficiendi at</span> has, in usu nusquam noluisse, no nam natum verterem. Eu tation dignissim pro. Id eos wisi mollis commune</p> 
 
    <p>Ea has quando blandit <a href="#a1">intellegebat, iusto</a> fabulas eos in, per consul suscipit inciderint cu. Ea veri possim nostrud vis. Id civibi. Ut duo posse <a href="#a2">graecis voluptatibus</a>, mea eu errem possim quaestio.</p> 
 
</div>

In dem obigen Beispiel I Optionen gaben Sie (Original Copy/Paste und spezielle copy/paste) spielen können.
Sie können sehen, dass in dem Beispiel der speziellen Kopie - ich baute die html Zeichenfolge in die Zwischenablage aus der Auswahl auf der Seite (basierend auf den DOM Elemente). Auf diese Weise konnte ich den genauen Wert des href erhalten (ohne ihn in den absoluten Pfad zu ändern).

Für Ihre bequeme, die exakt gleiche Code in jsfiddle: https://jsfiddle.net/m0ad3uaa/

1

Das Problem ist clientseitige. Browser kopieren Links mit absoluten URLs, um Probleme beim Einfügen von Links in verschiedene Bereiche zu vermeiden.

Zum Beispiel, wenn ich auf einen Link auf http://site1.com klicke, der so aussieht <a href="/myresource.jpg">, werde ich zu http://site1.com/myresource.jpg geleitet werden.

Nun, wenn Sie das gleiche Tag zu http://site2.com kopieren würden, würde der Link jetzt auf http://site2.com/myresource.jpg zeigen, die möglicherweise vorhanden ist oder nicht vorhanden ist.

Dies ist in den meisten Fällen sinnvoll. Wenn Sie Chrome verwenden, ist es unwahrscheinlich, dass Sie versuchen, eine Website, Assets und alles andere zu kopieren. Es behebt auch Probleme, bei denen die Tags auf nicht vorhandene Ressourcen zeigen.

Wenn Sie das alles sagen, ist es jedoch möglich, programmatisch mit dem, was ausgewählt wird, zu verfahren.

Es ist ein großartiges Beispiel dafür hier: http://bavotasan.com/2010/add-a-copyright-notice-to-copied-text/

Im Wesentlichen Sie wollen nur document.oncopy ändern window.getSelection() zu nehmen und alle Instanzen Ihres Domainnamen entfernen, um sicherzustellen, dass die Links stattdessen relativ sind.

+0

Können Sie sagen, wie genau Ihre Antwort neue Informationen liefert, die zu dieser Frage noch nicht existieren? – Dekel