Update home and MBViewer
This commit is contained in:
parent
9acf326d92
commit
5730543a94
|
@ -104,6 +104,7 @@ Body {
|
||||||
background-attachment: local, local, scroll, scroll;
|
background-attachment: local, local, scroll, scroll;
|
||||||
*/
|
*/
|
||||||
Background-Color: RGBA(36, 36, 36, 0.85);
|
Background-Color: RGBA(36, 36, 36, 0.85);
|
||||||
|
Font-Size: Larger;
|
||||||
}
|
}
|
||||||
.Footer > .FooterRight { Margin-Right: 12px; }
|
.Footer > .FooterRight { Margin-Right: 12px; }
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ function _TransformForOutput (transformerTree, initOptions, entityName, upstream
|
||||||
// TODO: 'document' won't work on nodejs, must change it
|
// TODO: 'document' won't work on nodejs, must change it
|
||||||
function GetElementsByXPath (xpath, parent) {
|
function GetElementsByXPath (xpath, parent) {
|
||||||
let results = [];
|
let results = [];
|
||||||
let query = document.evaluate(xpath, parent || document, ((ns) => ns), XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
let query = (parent?.getRootNode() || document).evaluate(xpath, (parent || document), ((ns) => ns), XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
for (let i=0, length=query.snapshotLength; i<length; ++i) {
|
for (let i=0, length=query.snapshotLength; i<length; ++i) {
|
||||||
results.push(query.snapshotItem(i));
|
results.push(query.snapshotItem(i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* Sanitize an HTML string
|
||||||
|
* (c) Chris Ferdinandi, MIT License, https://gomakethings.com
|
||||||
|
* @param {String} str The HTML string to sanitize
|
||||||
|
* @param {Boolean} nodes If true, returns HTML nodes instead of a string
|
||||||
|
* @return {String|NodeList} The sanitized string or nodes
|
||||||
|
*/
|
||||||
|
function cleanHTML (str, nodes) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the string to an HTML document
|
||||||
|
* @return {Node} An HTML document
|
||||||
|
*/
|
||||||
|
function stringToHTML () {
|
||||||
|
let parser = new DOMParser();
|
||||||
|
let doc = parser.parseFromString(str, 'text/html');
|
||||||
|
return doc.body || document.createElement('body');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove <script> elements
|
||||||
|
* @param {Node} html The HTML
|
||||||
|
*/
|
||||||
|
function removeScripts (html) {
|
||||||
|
let scripts = html.querySelectorAll('script');
|
||||||
|
for (let script of scripts) {
|
||||||
|
script.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the attribute is potentially dangerous
|
||||||
|
* @param {String} name The attribute name
|
||||||
|
* @param {String} value The attribute value
|
||||||
|
* @return {Boolean} If true, the attribute is potentially dangerous
|
||||||
|
*/
|
||||||
|
function isPossiblyDangerous (name, value) {
|
||||||
|
let val = value.replace(/\s+/g, '').toLowerCase();
|
||||||
|
if (['src', 'href', 'xlink:href'].includes(name)) {
|
||||||
|
if (val.includes('javascript:') || val.includes('data:')) return true;
|
||||||
|
}
|
||||||
|
if (name.startsWith('on')) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove potentially dangerous attributes from an element
|
||||||
|
* @param {Node} elem The element
|
||||||
|
*/
|
||||||
|
function removeAttributes (elem) {
|
||||||
|
|
||||||
|
// Loop through each attribute
|
||||||
|
// If it's dangerous, remove it
|
||||||
|
let atts = elem.attributes;
|
||||||
|
for (let {name, value} of atts) {
|
||||||
|
if (!isPossiblyDangerous(name, value)) continue;
|
||||||
|
elem.removeAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove dangerous stuff from the HTML document's nodes
|
||||||
|
* @param {Node} html The HTML document
|
||||||
|
*/
|
||||||
|
function clean (html) {
|
||||||
|
let nodes = html.children;
|
||||||
|
for (let node of nodes) {
|
||||||
|
removeAttributes(node);
|
||||||
|
clean(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the string to HTML
|
||||||
|
let html = stringToHTML();
|
||||||
|
|
||||||
|
// Sanitize it
|
||||||
|
removeScripts(html);
|
||||||
|
clean(html);
|
||||||
|
|
||||||
|
// If the user wants HTML nodes back, return them
|
||||||
|
// Otherwise, pass a sanitized string back
|
||||||
|
return nodes ? html.childNodes : html.innerHTML;
|
||||||
|
|
||||||
|
}
|
|
@ -207,6 +207,7 @@
|
||||||
<script src="../Assets/Lib/lodash.custom.min.js"></script>
|
<script src="../Assets/Lib/lodash.custom.min.js"></script>
|
||||||
<script src="../Assets/Lib/defiant.min.js"></script>
|
<script src="../Assets/Lib/defiant.min.js"></script>
|
||||||
<script src="../Assets/Lib/Trasformapi.js"></script>
|
<script src="../Assets/Lib/Trasformapi.js"></script>
|
||||||
|
<script src="../Assets/Lib/cleanHTML.js"></script>
|
||||||
<script src="./js/TrasformapiSchema.js.xml"></script>
|
<script src="./js/TrasformapiSchema.js.xml"></script>
|
||||||
<script src="./js/MBViewer.js"></script>
|
<script src="./js/MBViewer.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -7,18 +7,16 @@
|
||||||
// * in-app search of site content
|
// * in-app search of site content
|
||||||
// * homepage with history and sponsored sources
|
// * homepage with history and sponsored sources
|
||||||
// * don't show redundant day markers
|
// * don't show redundant day markers
|
||||||
// * other supported sources
|
// * fetch and compile to show Markdown WordPress export pages from Git?
|
||||||
// ** Markdown WordPress export pages from Git?
|
// * app info in main page without JS?
|
||||||
// ** Atom/RSS feeds
|
// * fix some messages being skipped when connection errors happen (already done?)
|
||||||
// * app info in page without JS?
|
|
||||||
// * fix some messages being skipped when connection errors happen
|
|
||||||
// * optionally show post titles?
|
// * optionally show post titles?
|
||||||
// * fix unfinished tasks still executing when clicking back
|
// * fix some unfinished tasks still executing when clicking back
|
||||||
// * fix imported SVG buttons not fitting with dark theme
|
|
||||||
// * I think we might need to handle acronicized names for users when needed?
|
// * I think we might need to handle acronicized names for users when needed?
|
||||||
// * show, and/or sort by, posts tags/categories
|
// * show, and/or sort by, posts tags/categories
|
||||||
// * scroll to post id when loading from dataInject or RSS
|
// * scroll to post id when loading from dataInject or RSS
|
||||||
// * fix XML feeds parsing on Firefox
|
// * fix XML feeds parsing on Firefox
|
||||||
|
// * allow for an HTML transformation script to be loaded (JS is unsafe) (how?)
|
||||||
|
|
||||||
let MbState = {};
|
let MbState = {};
|
||||||
let MbApiTransformer;
|
let MbApiTransformer;
|
||||||
|
@ -374,7 +372,7 @@ async function MbViewerInit () {
|
||||||
So, here are some new changes:
|
So, here are some new changes:
|
||||||
<br/> * Fixed video embed fullscreen, and added a reload button in case load fails
|
<br/> * Fixed video embed fullscreen, and added a reload button in case load fails
|
||||||
<br/> * Initial support for handling data via Trasformapi lib
|
<br/> * Initial support for handling data via Trasformapi lib
|
||||||
<br/> * Initial, experimental support for RSS feeds specifically, via Transformapi (very broken)
|
<br/> * Initial, experimental support for RSS feeds specifically, via Trasformapi (very broken)
|
||||||
</p>`, time: '2024-01-23T01:00' }, { content: `<p>
|
</p>`, time: '2024-01-23T01:00' }, { content: `<p>
|
||||||
New changes:
|
New changes:
|
||||||
<br/> * Updated Trasformapi.js with misc fixes, query constants, and streamlined/powerful data querying
|
<br/> * Updated Trasformapi.js with misc fixes, query constants, and streamlined/powerful data querying
|
||||||
|
@ -389,6 +387,11 @@ async function MbViewerInit () {
|
||||||
Regarding Trasformapi, I transformed some of my development tears into words, read here if you're curious:
|
Regarding Trasformapi, I transformed some of my development tears into words, read here if you're curious:
|
||||||
<a href="https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/">https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/</a>.
|
<a href="https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/">https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/</a>.
|
||||||
</p>`, time: '2024-01-25T01:00' }, { content: `<p>
|
</p>`, time: '2024-01-25T01:00' }, { content: `<p>
|
||||||
|
Some small things:
|
||||||
|
<br/> * Fixed RSS feeds parsing on Firefox (mentioned in the post linked above), by fixing a bug in Trasformapi
|
||||||
|
<br/> * HTML is now sanitized for removal of dangerous tags and attributes before displaying
|
||||||
|
<br/> * Support including user-defined CSS rules from URL (<code>data:</code> supported) via the "<code>includeStyle</code>" argument
|
||||||
|
</p>`, time: '2024-01-27T20:00' }, { content: `<p>
|
||||||
Copyright notice: MBViewer uses code borrowed from <a href="https://t.me">t.me</a>,
|
Copyright notice: MBViewer uses code borrowed from <a href="https://t.me">t.me</a>,
|
||||||
specially modified to handle customized data visualizations in an MB-style.
|
specially modified to handle customized data visualizations in an MB-style.
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -405,6 +408,18 @@ async function MbViewerInit () {
|
||||||
} else {
|
} else {
|
||||||
$('.tgme_page_photo_image').addClass(`bgcolor${MbState.siteData.bgColor}`);
|
$('.tgme_page_photo_image').addClass(`bgcolor${MbState.siteData.bgColor}`);
|
||||||
}
|
}
|
||||||
|
RefreshIncludeStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function RefreshIncludeStyle () {
|
||||||
|
document.querySelector('link[href][rel="stylesheet"]#MbViewerIncludeStyle')?.remove();
|
||||||
|
if (MbState.args.includestyle) {
|
||||||
|
const linkElem = document.createElement('link');
|
||||||
|
linkElem.id = 'MbViewerIncludeStyle';
|
||||||
|
linkElem.rel = 'stylesheet';
|
||||||
|
linkElem.href = MbState.args.includestyle;
|
||||||
|
document.body.appendChild(linkElem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function MakeMoreWrapperHtml (wrapType) {
|
function MakeMoreWrapperHtml (wrapType) {
|
||||||
|
@ -533,7 +548,7 @@ async function MakeMbHtml (postData, makeMoreWrap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReformatPostHtml (html) {
|
function ReformatPostHtml (html) {
|
||||||
const content = $(`<div>${html}</div>`);
|
const content = $(`<div>${cleanHTML(html, false)}</div>`);
|
||||||
// bypass Altervista's anti-hotlinking protection by hiding our HTTP Referer header
|
// bypass Altervista's anti-hotlinking protection by hiding our HTTP Referer header
|
||||||
// TODO: only do this for altervista sites maybe
|
// TODO: only do this for altervista sites maybe
|
||||||
if (MbState.platform === 'wordpress.org') {
|
if (MbState.platform === 'wordpress.org') {
|
||||||
|
@ -589,7 +604,7 @@ function ResizeLayouts () {
|
||||||
}
|
}
|
||||||
|
|
||||||
$('a[name="goBack"]')[0].onclick = function(){
|
$('a[name="goBack"]')[0].onclick = function(){
|
||||||
ArgsRewrite({ dataurl: null, siteurl: null, postid: null, platform: null, /*postslug: null*/ });
|
ArgsRewrite({ dataurl: null, siteurl: null, postid: null, platform: null, includestyle: null /*postslug: null*/ });
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onmessage = function(event){
|
window.onmessage = function(event){
|
||||||
|
|
Loading…
Reference in New Issue