The reactive statement that triggers a bookmark update included
"bookmarkId", meaning that an update would be triggered after saving
(bookmarkId goes from empty to a value), regardless of the (unchanged)
state of the other attributes.
This moves the test on bookmarkId in a sub function so its value doesn't
trigger the reactive statement.
Resolves#121
This adds an "Accept" header in fetchResource with some priorities when
it comes to images. JPEG and PNG is favored over formats like webp
(avoiding a conversion to JPEG or PNG again).
This avoid prioritizing AVIF that Readeck can't decode.
Resolves#122
This avoids the bookmark save process getting aborted when even a single canvas
element on the page is "tainted", i.e. it embeds cross-site content and
browsers thus prohibit to capture its data as an image.
For easier debugging in both development and production, this configuration
change unconditionally enables source maps so that using devtools in a browser
would print the original source locations in stack traces.
- Enable the "recommended" set of eslint rules across the whole project
- Fix violations due to "no-unused-vars"
- Declare in eslint configuration which source files we expect to be CommonJS and which are ESM
- Remove "async" from functions that shouldn't have it
The new Shadow DOM cloning approach avoids issues with browser warning about
adopted stylesheets. However, now that we do shadow DOM cloning, mapping cloned
image elements to their original elements (so that they can be measured) is a
bit more non-trivial. The updated approach builds a map of all image elements
and tags them with a temporary HTML attribute so that mapping post-cloning can
be performed un-ambiguously.
Closes#111
Followup to #110, 9516287866
Original author: @mislav
Apologies for accidentally removed the remote branch from #112...
When an element hosts a Shadow DOM, its contents will appear empty using
traditional DOM traversal:
const myEl = document.querySelector("my-custom-element")
myEl.firstChild //=> null
myEl.shadowRoot //=> ShadowRoot
and if that host ever gets cloned, it will be completely empty and not even
host to any Shadow DOM anymore:
const clonedEl = myEl.cloneNode(true)
clonedEl.firstChild //=> null
clonedEl.shadowRoot //=> null
The Readeck browser extension captures page content by cloning the original
document and serializing it using `outerHTML`:
page.content = clonedDoc.documentElement.outerHTML
but because of how Shadow DOM behaves, this serialization method will never be
able to capture the contents of elements that are hosts to a Shadow DOM.
This change makes sure that all elements that are Shadow DOM hosts are
explicitly serialized using `el.getHTML()`.
Ref. https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM
Adds support for:
<object type="image/*" data="{href}">Alt text here</object>
by adding href to prefetch URLs.
Also adds support for:
<canvas></canvas>
by rasterizing the canvas element to an image with a "data:" URL.
When sending page HTML to Readeck, this populates "data-readeck-width" and
"data-readeck-height" attributes with display dimensions for each image.
This will help the Readeck backend decide how to process images based on their
display dimensions which take CSS into account, rather than by their physical
dimensions. This is especially useful for SVG icons which the Readeck backend
wants to strip away, but whose `viewport` and width/height dimensions as
indicated by their markup often does not reflect their final display dimensions.
The current flow is quite complex and relies on listeners that can be
conflicting with other extensions.
This is a much simpler approach:
- the OAuth redirection is a real, web accessible, resource
- the redirection page sends a message to the extension with its
query parameters
- the oauthPrompt function listens to the message and resolves with
the authorization result
And that's it!
This adds the oauth-callback.html page to "web_accessible_resources"
for any http or https URL.
Incidentally, this resolves#93