Skip to content
24 changes: 22 additions & 2 deletions assets/bookmarklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
encURI = window.encodeURIComponent,
head = document.getElementsByTagName( 'head' )[0],
target = '_press_this_app',
windowWidth, windowHeight, selection,
windowWidth, windowHeight, selection, selectionHtml,
metas, links, content, images, iframes, img, scripts,
scrapedData = {},
popup;
Expand All @@ -32,7 +32,22 @@
}

if ( window.getSelection ) {
selection = window.getSelection() + '';
var sel = window.getSelection();
if ( sel && sel.rangeCount > 0 ) {
selection = sel.toString();
// Capture HTML to preserve formatting (bold, lists, headings, etc.).
// Wrapped in try-catch: cloneContents() can throw DOMException in
// some browsers or unusual DOM states (e.g. cross-shadow-DOM ranges).
try {
var range = sel.getRangeAt( 0 );
var fragment = range.cloneContents();
var tempDiv = document.createElement( 'div' );
tempDiv.appendChild( fragment );
selectionHtml = tempDiv.innerHTML;
} catch ( e ) {
// HTML capture failed; plain-text selection is still available.
}
}
} else if ( document.getSelection ) {
selection = document.getSelection() + '';
} else if ( document.selection ) {
Expand Down Expand Up @@ -299,6 +314,11 @@
add( 's', selection );
}

// Add HTML selection to preserve formatting (bold, lists, headings, etc.).
if ( selectionHtml ) {
add( 'sel_html', selectionHtml );
}

/**
* Send scraped data to the Press This popup via postMessage.
* Uses polling to wait for the popup to be ready.
Expand Down
2 changes: 1 addition & 1 deletion assets/bookmarklet.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,13 @@ export default function App() {
// Build suggested content from bookmarklet metadata.
// Extract description from meta tags.
const meta = messageData._meta || {};

// HTML selection takes highest priority (preserves formatting).
// Always compute plain-text description as a fallback; buildSuggestedContent
// will use it if htmlToBlocks() produces no blocks from selectionHtml.
const selectionHtml = messageData.sel_html || '';
const description =
messageData.s || // User selection takes priority.
messageData.s || // Plain-text user selection.
meta[ 'twitter:description' ] ||
meta[ 'og:description' ] ||
meta.description ||
Expand All @@ -243,6 +248,7 @@ export default function App() {
const suggestedContent = buildSuggestedContentFromMetadata( {
title,
description,
selectionHtml,
siteName: meta[ 'og:site_name' ] || '',
canonical,
url: receivedSourceUrl,
Expand Down
6 changes: 5 additions & 1 deletion src/components/BlockTransformShortcuts.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@ export default function BlockTransformShortcuts() {
if ( innerBlocks.length > 0 ) {
// Replace the quote with its inner blocks directly.
const replacementBlocks = innerBlocks.map( ( inner ) =>
createBlock( inner.name, { ...inner.attributes }, inner.innerBlocks )
createBlock(
inner.name,
{ ...inner.attributes },
inner.innerBlocks
)
);
replaceBlocks( currentClientId, replacementBlocks );
} else {
Expand Down
Loading
Loading