more proxy work
This commit is contained in:
@@ -8,6 +8,7 @@ class WTVMinifyingProxy {
|
|||||||
|
|
||||||
// HTML 3.0/4.0 compatible tags and attributes
|
// HTML 3.0/4.0 compatible tags and attributes
|
||||||
this.allowedTags = [
|
this.allowedTags = [
|
||||||
|
'audioscope', 'bgsound', 'marquee', 'wtvchattranscript', 'wtvchat',
|
||||||
'html', 'head', 'title', 'meta', 'body', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
'html', 'head', 'title', 'meta', 'body', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||||
'p', 'br', 'hr', 'div', 'span', 'a', 'img', 'ul', 'ol', 'li', 'table', 'tr',
|
'p', 'br', 'hr', 'div', 'span', 'a', 'img', 'ul', 'ol', 'li', 'table', 'tr',
|
||||||
'td', 'th', 'tbody', 'thead', 'tfoot', 'form', 'input', 'textarea', 'select',
|
'td', 'th', 'tbody', 'thead', 'tfoot', 'form', 'input', 'textarea', 'select',
|
||||||
@@ -16,6 +17,9 @@ class WTVMinifyingProxy {
|
|||||||
];
|
];
|
||||||
|
|
||||||
this.allowedAttributes = [
|
this.allowedAttributes = [
|
||||||
|
'leftcolor', 'rightcolor', 'maxlevel', 'leftoffset', 'rightoffset',
|
||||||
|
'host', 'port', 'channel', 'borderimage', 'font', 'nohighlight', 'autoactivate',
|
||||||
|
'text', 'cursor',
|
||||||
'href', 'src', 'alt', 'title', 'width', 'height', 'border', 'align', 'valign',
|
'href', 'src', 'alt', 'title', 'width', 'height', 'border', 'align', 'valign',
|
||||||
'bgcolor', 'color', 'size', 'face', 'target', 'name', 'value', 'type', 'action',
|
'bgcolor', 'color', 'size', 'face', 'target', 'name', 'value', 'type', 'action',
|
||||||
'method', 'cols', 'rows', 'cellpadding', 'cellspacing', 'nowrap',
|
'method', 'cols', 'rows', 'cellpadding', 'cellspacing', 'nowrap',
|
||||||
@@ -171,8 +175,8 @@ class WTVMinifyingProxy {
|
|||||||
html = html.replace(/<(\w+)([^>]*)\s+style\s*=\s*["']([^"']+)["']([^>]*?)(\s*\/?)>/gi, (match, tagName, beforeStyle, styles, afterStyle, selfClosing) => {
|
html = html.replace(/<(\w+)([^>]*)\s+style\s*=\s*["']([^"']+)["']([^>]*?)(\s*\/?)>/gi, (match, tagName, beforeStyle, styles, afterStyle, selfClosing) => {
|
||||||
const result = this.parseStyleToAttributes(styles, tagName);
|
const result = this.parseStyleToAttributes(styles, tagName);
|
||||||
|
|
||||||
if (result.fontSize && !/^(input|select|textarea)$/i.test(tagName)) {
|
if (result.fontSize) {
|
||||||
// For non-form elements with font-size, wrap in font tag
|
// For all elements with font-size, wrap in font tag
|
||||||
const elementWithAttributes = result.attributes ?
|
const elementWithAttributes = result.attributes ?
|
||||||
`<${tagName}${beforeStyle} ${result.attributes}${afterStyle}${selfClosing}>` :
|
`<${tagName}${beforeStyle} ${result.attributes}${afterStyle}${selfClosing}>` :
|
||||||
`<${tagName}${beforeStyle}${afterStyle}${selfClosing}>`;
|
`<${tagName}${beforeStyle}${afterStyle}${selfClosing}>`;
|
||||||
@@ -217,30 +221,61 @@ class WTVMinifyingProxy {
|
|||||||
|
|
||||||
styles.forEach(style => {
|
styles.forEach(style => {
|
||||||
const [property, value] = style.split(':').map(s => s.trim());
|
const [property, value] = style.split(':').map(s => s.trim());
|
||||||
if (property && value && this.cssToHtml[property]) {
|
if (property && value) {
|
||||||
let htmlValue = value;
|
let htmlValue = value;
|
||||||
|
|
||||||
// Convert CSS values to HTML equivalents
|
// Convert CSS values to HTML equivalents
|
||||||
if (property === 'font-size') {
|
if (property === 'font-size') {
|
||||||
htmlValue = this.convertFontSize(value);
|
htmlValue = this.convertFontSize(value);
|
||||||
|
|
||||||
// Handle font-size differently for form vs non-form elements
|
// For all elements, font-size should use font tag wrapping, not size attribute
|
||||||
const isFormElement = /^(input|select|textarea)$/i.test(elementTag);
|
fontSize = htmlValue;
|
||||||
if (isFormElement) {
|
return;
|
||||||
// For form elements, add size attribute directly
|
} else if (property === 'color') {
|
||||||
attributes.push(`${this.cssToHtml[property]}="${htmlValue}"`);
|
htmlValue = this.convertColor(value);
|
||||||
|
|
||||||
|
// WebTV-specific color handling based on element type
|
||||||
|
if (/^(input|textarea)$/i.test(elementTag)) {
|
||||||
|
// Forms support both 'color' and 'text' attributes for text color
|
||||||
|
attributes.push(`text="${htmlValue}"`);
|
||||||
|
} else if (/^(button)$/i.test(elementTag)) {
|
||||||
|
// Buttons support 'text' attribute but not bgcolor
|
||||||
|
attributes.push(`text="${htmlValue}"`);
|
||||||
|
} else if (/^(select)$/i.test(elementTag)) {
|
||||||
|
// Select menus don't support color attributes - skip
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
// For non-form elements, store font size for font tag wrapping
|
// Other elements use standard 'color' attribute
|
||||||
fontSize = htmlValue;
|
attributes.push(`color="${htmlValue}"`);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (property === 'color' || property === 'background-color') {
|
} else if (property === 'background-color') {
|
||||||
htmlValue = this.convertColor(value);
|
htmlValue = this.convertColor(value);
|
||||||
} else if (property === 'width' || property === 'height') {
|
|
||||||
htmlValue = this.convertDimension(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes.push(`${this.cssToHtml[property]}="${htmlValue}"`);
|
// WebTV-specific background color handling
|
||||||
|
if (/^(input|textarea)$/i.test(elementTag)) {
|
||||||
|
// Forms support bgcolor attribute
|
||||||
|
attributes.push(`bgcolor="${htmlValue}"`);
|
||||||
|
} else if (/^(button|select)$/i.test(elementTag)) {
|
||||||
|
// Buttons and select menus don't support bgcolor - skip
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Other elements use standard bgcolor
|
||||||
|
attributes.push(`bgcolor="${htmlValue}"`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (property === 'caret-color' && /^(input|textarea)$/i.test(elementTag)) {
|
||||||
|
// WebTV cursor attribute for text cursor color in forms
|
||||||
|
htmlValue = this.convertColor(value);
|
||||||
|
attributes.push(`cursor="${htmlValue}"`);
|
||||||
|
return;
|
||||||
|
} else if (this.cssToHtml[property]) {
|
||||||
|
// Handle other standard CSS-to-HTML conversions
|
||||||
|
if (property === 'width' || property === 'height') {
|
||||||
|
htmlValue = this.convertDimension(value);
|
||||||
|
}
|
||||||
|
attributes.push(`${this.cssToHtml[property]}="${htmlValue}"`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -266,42 +301,30 @@ class WTVMinifyingProxy {
|
|||||||
if (attributes) {
|
if (attributes) {
|
||||||
let newTagContent = tagContent;
|
let newTagContent = tagContent;
|
||||||
|
|
||||||
// Special handling for input elements: WebTV prioritizes size over width
|
// Special handling for input elements: WebTV prioritizes width over size
|
||||||
if (attributes.includes('width=')) {
|
if (attributes.includes('width=')) {
|
||||||
const existingSize = tagContent.match(/size\s*=\s*["']?(\d+)["']?/i);
|
const existingSize = tagContent.match(/size\s*=\s*["']?(\d+)["']?/i);
|
||||||
const widthMatch = attributes.match(/width="(\d+)"/);
|
const widthMatch = attributes.match(/width="(\d+)"/);
|
||||||
|
|
||||||
if (existingSize && widthMatch) {
|
if (existingSize && widthMatch) {
|
||||||
// Both size and width exist - for WebTV, recalculate size based on CSS width
|
// Both size and width exist - for WebTV, prioritize width, remove size
|
||||||
const cssWidth = parseInt(widthMatch[1]);
|
newTagContent = tagContent.replace(/\s*size\s*=\s*["']?\d+["']?/i, '');
|
||||||
const currentSize = parseInt(existingSize[1]);
|
|
||||||
// Use larger of the two for better WebTV compatibility
|
|
||||||
const betterSize = Math.max(Math.round(cssWidth / 8), currentSize);
|
|
||||||
|
|
||||||
// Replace the existing size with the better calculated size
|
// Add all attributes including width
|
||||||
newTagContent = tagContent.replace(/size\s*=\s*["']?\d+["']?/i, `size="${betterSize}"`);
|
newTagContent = `${newTagContent} ${attributes}`;
|
||||||
|
|
||||||
// Add other attributes except width
|
|
||||||
const filteredAttributes = attributes.replace(/width="[^"]*"/, '').trim();
|
|
||||||
if (filteredAttributes) {
|
|
||||||
newTagContent = `${newTagContent} ${filteredAttributes}`;
|
|
||||||
}
|
|
||||||
} else if (existingSize) {
|
} else if (existingSize) {
|
||||||
// If input already has size attribute, don't add width
|
// If input already has size attribute, replace with width if available
|
||||||
const filteredAttributes = attributes.replace(/\s*width="[^"]*"/, '');
|
newTagContent = tagContent.replace(/\s*size\s*=\s*["']?\d+["']?/i, '');
|
||||||
newTagContent = `${tagContent} ${filteredAttributes}`;
|
newTagContent = `${newTagContent} ${attributes}`;
|
||||||
} else {
|
} else {
|
||||||
// Convert width to size if no existing size
|
// Add width and other attributes normally
|
||||||
const pixelWidth = parseInt(widthMatch[1]);
|
newTagContent = `${tagContent} ${attributes}`;
|
||||||
// Rough conversion: ~8-10 pixels per character for WebTV
|
|
||||||
const charSize = Math.round(pixelWidth / 8);
|
|
||||||
const sizeAttr = `size="${Math.min(charSize, 80)}"`; // Cap at 80 chars
|
|
||||||
const otherAttributes = attributes.replace(/width="[^"]*"/, '').trim();
|
|
||||||
const finalAttributes = otherAttributes ? `${sizeAttr} ${otherAttributes}` : sizeAttr;
|
|
||||||
newTagContent = `${tagContent} ${finalAttributes}`;
|
|
||||||
}
|
}
|
||||||
|
} else if (attributes.includes('size=')) {
|
||||||
|
// Only font-size, no width - use size attribute
|
||||||
|
newTagContent = `${tagContent} ${attributes}`;
|
||||||
} else {
|
} else {
|
||||||
// No width attribute, add all attributes normally
|
// No width or size attributes, add all attributes normally
|
||||||
newTagContent = `${tagContent} ${attributes}`;
|
newTagContent = `${tagContent} ${attributes}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,8 +336,19 @@ class WTVMinifyingProxy {
|
|||||||
// Also handle non-input elements with this class
|
// Also handle non-input elements with this class
|
||||||
const generalRegex = new RegExp(`<((?!input)[^>]+class\\s*=\\s*["'][^"']*\\b${className}\\b[^"']*["'][^>]*)>`, 'gi');
|
const generalRegex = new RegExp(`<((?!input)[^>]+class\\s*=\\s*["'][^"']*\\b${className}\\b[^"']*["'][^>]*)>`, 'gi');
|
||||||
html = html.replace(generalRegex, (match, tagContent) => {
|
html = html.replace(generalRegex, (match, tagContent) => {
|
||||||
const attributes = this.parseStyleToAttributes(styles);
|
// Extract tag name to properly handle attributes
|
||||||
if (attributes) {
|
const tagMatch = tagContent.match(/^(\w+)/);
|
||||||
|
const tagName = tagMatch ? tagMatch[1] : '';
|
||||||
|
|
||||||
|
const result = this.parseStyleToAttributes(styles, tagName);
|
||||||
|
const attributes = result.attributes || '';
|
||||||
|
|
||||||
|
if (result.fontSize) {
|
||||||
|
// Wrap all elements with font-size in font tags
|
||||||
|
const elementWithAttributes = attributes ?
|
||||||
|
`<${tagContent} ${attributes}>` : `<${tagContent}>`;
|
||||||
|
return `<font size="${result.fontSize}">${elementWithAttributes}`;
|
||||||
|
} else if (attributes) {
|
||||||
return `<${tagContent} ${attributes}>`;
|
return `<${tagContent} ${attributes}>`;
|
||||||
}
|
}
|
||||||
return match;
|
return match;
|
||||||
@@ -443,6 +477,9 @@ class WTVMinifyingProxy {
|
|||||||
return `<input ${attributes}>`;
|
return `<input ${attributes}>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add WebTV-specific enhancements for better layout
|
||||||
|
html = this.addWebTVLayoutEnhancements(html);
|
||||||
|
|
||||||
// Fix submit buttons to have better sizing for WebTV
|
// Fix submit buttons to have better sizing for WebTV
|
||||||
html = html.replace(/<input([^>]*type="submit"[^>]*)>/gi, (match, attributes) => {
|
html = html.replace(/<input([^>]*type="submit"[^>]*)>/gi, (match, attributes) => {
|
||||||
// Add width if not present to make buttons more visible
|
// Add width if not present to make buttons more visible
|
||||||
@@ -794,6 +831,86 @@ ${bodyContent}
|
|||||||
return `<img${attrs}>`;
|
return `<img${attrs}>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add WebTV-specific layout enhancements
|
||||||
|
*/
|
||||||
|
addWebTVLayoutEnhancements(html) {
|
||||||
|
// Ensure input elements have minimum sizing for WebTV visibility
|
||||||
|
html = html.replace(/<input([^>]*type=["']?text["']?[^>]*)>/gi, (match, attributes) => {
|
||||||
|
let newAttributes = attributes;
|
||||||
|
|
||||||
|
// Check if width exists and ensure it's reasonable for WebTV
|
||||||
|
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
||||||
|
if (widthMatch) {
|
||||||
|
let width = parseInt(widthMatch[1]);
|
||||||
|
// Ensure minimum width of 200px for text inputs on WebTV
|
||||||
|
if (width < 200) {
|
||||||
|
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="200"`);
|
||||||
|
}
|
||||||
|
// Cap maximum width at 400px for WebTV compatibility
|
||||||
|
else if (width > 400) {
|
||||||
|
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="400"`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add default width if none exists
|
||||||
|
newAttributes += ` width="250"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure minimum height for better visibility
|
||||||
|
if (!attributes.includes('height=')) {
|
||||||
|
newAttributes += ` height="25"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<input ${newAttributes}>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enhance table layouts for better WebTV rendering
|
||||||
|
html = html.replace(/<table([^>]*)>/gi, (match, attributes) => {
|
||||||
|
let newAttributes = attributes;
|
||||||
|
|
||||||
|
// Ensure tables have explicit widths for WebTV
|
||||||
|
if (!attributes.includes('width=')) {
|
||||||
|
newAttributes += ` width="100%"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add cellpadding and cellspacing if not present
|
||||||
|
if (!attributes.includes('cellpadding=')) {
|
||||||
|
newAttributes += ` cellpadding="4"`;
|
||||||
|
}
|
||||||
|
if (!attributes.includes('cellspacing=')) {
|
||||||
|
newAttributes += ` cellspacing="2"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<table${newAttributes}>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Don't auto-wrap forms in tables - enhance existing structure instead
|
||||||
|
// The original HTML likely already has proper table structure
|
||||||
|
|
||||||
|
// Ensure submit buttons have minimum height for WebTV
|
||||||
|
html = html.replace(/<input([^>]*type=["']?submit["']?[^>]*)>/gi, (match, attributes) => {
|
||||||
|
let newAttributes = attributes;
|
||||||
|
|
||||||
|
// Ensure minimum height for buttons
|
||||||
|
if (!attributes.includes('height=')) {
|
||||||
|
newAttributes += ` height="30"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure minimum width for buttons
|
||||||
|
const widthMatch = attributes.match(/width\s*=\s*["']?(\d+)["']?/);
|
||||||
|
if (widthMatch) {
|
||||||
|
let width = parseInt(widthMatch[1]);
|
||||||
|
if (width < 80) {
|
||||||
|
newAttributes = attributes.replace(/width\s*=\s*["']?\d+["']?/, `width="80"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<input ${newAttributes}>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = WTVMinifyingProxy;
|
module.exports = WTVMinifyingProxy;
|
||||||
|
|||||||
Reference in New Issue
Block a user