228 lines
5.8 KiB
TypeScript
228 lines
5.8 KiB
TypeScript
|
|
import { HTMLNodeTreeWalker } from "../graphs/HTMLNodeTreeWalker";
|
|
import { DOMNameSpaces } from "./DOMNameSpaces";
|
|
import { ElementAttribute } from "./ElementAttribute";
|
|
|
|
export class ResolvablePathAttribute
|
|
{
|
|
private _selector:string;
|
|
private _attribute:ElementAttribute
|
|
|
|
constructor( selector:string, attribute:string, namespace?:string )
|
|
{
|
|
this._selector = selector;
|
|
this._attribute = new ElementAttribute( attribute, false, namespace );
|
|
}
|
|
|
|
|
|
get combinedSelector()
|
|
{
|
|
let combined = `${this._selector}${this._attribute.selector}`;
|
|
|
|
return combined;
|
|
}
|
|
|
|
get useNodeNameMatcher()
|
|
{
|
|
return this._selector === "image";
|
|
}
|
|
|
|
getFrom( target:Element|Document )
|
|
{
|
|
if ( this.useNodeNameMatcher )
|
|
{
|
|
let matchedElements:Element[] = [];
|
|
|
|
let walker = new HTMLNodeTreeWalker();
|
|
|
|
let walkable = target;
|
|
if ( ( target as Document ).documentElement )
|
|
{
|
|
walkable = ( target as Document).documentElement;
|
|
}
|
|
|
|
walker.forAll( walkable,
|
|
n =>
|
|
{
|
|
if ( n.nodeName === this._selector )
|
|
{
|
|
matchedElements.push( n as Element );
|
|
}
|
|
}
|
|
);
|
|
|
|
return matchedElements;
|
|
}
|
|
|
|
let elements = target.querySelectorAll( this.combinedSelector );
|
|
|
|
return Array.prototype.slice.call( elements );
|
|
}
|
|
|
|
|
|
process( element:Element, rootToken:string, rootPath:string )
|
|
{
|
|
let value = this._attribute.from( element );
|
|
|
|
if ( value === null )
|
|
{
|
|
if ( this._selector === "image" )
|
|
{
|
|
console.log( "no value for image" );
|
|
this.lgGetAttribute( element, "href" );
|
|
this.lgGetAttribute( element, "xlink:href" );
|
|
}
|
|
|
|
return;
|
|
}
|
|
else if ( this._selector === "image" )
|
|
{
|
|
|
|
}
|
|
|
|
/*if ( ! value.startsWith( rootToken ) )
|
|
{
|
|
if ( this._selector === "image" )
|
|
{
|
|
let shortValue = value;
|
|
|
|
if ( value.length > 100 )
|
|
{
|
|
shortValue = value.substring( 0, 100 );
|
|
}
|
|
|
|
|
|
}
|
|
else if ( this._attribute.name === "style" )
|
|
{
|
|
value = value.replace( rootToken, rootPath )
|
|
}
|
|
|
|
return;
|
|
}*/
|
|
|
|
value = value.replace( rootToken, rootPath )
|
|
|
|
this._attribute.to( element, value );
|
|
}
|
|
|
|
lgGetAttribute( element:Element, attribute:string )
|
|
{
|
|
this.lg( `${attribute} >> ${element.getAttribute( attribute )} `);
|
|
this.lg( `${attribute} NS=null >> ${element.getAttributeNS( null, attribute )} `);
|
|
this.lg( `${attribute} NS="" >> ${element.getAttributeNS( "", attribute )} `);
|
|
this.lg( `${attribute} NS=XLink >> ${element.getAttributeNS( DOMNameSpaces.XLink, attribute )} `);
|
|
this.lg( `${attribute} NS=SVG >> ${element.getAttributeNS( DOMNameSpaces.SVG, attribute )} `);
|
|
}
|
|
|
|
lg( value:string )
|
|
{
|
|
let shortValue = value;
|
|
|
|
if ( value.length > 100 )
|
|
{
|
|
shortValue = value.substring( 0, 100 ) + "...";
|
|
}
|
|
|
|
console.log( shortValue );
|
|
}
|
|
}
|
|
|
|
|
|
export class RootPathResolver
|
|
{
|
|
static readonly customResolve = new ElementAttribute( "resolve-root-path" );
|
|
|
|
static readonly resolvables:ResolvablePathAttribute[] =
|
|
[
|
|
new ResolvablePathAttribute( "link", "href" ),
|
|
new ResolvablePathAttribute( "script", "src" ),
|
|
new ResolvablePathAttribute( "a", "href" ),
|
|
new ResolvablePathAttribute( "img", "src" ),
|
|
new ResolvablePathAttribute( "audio", "src" ),
|
|
new ResolvablePathAttribute( "source", "src" ),
|
|
new ResolvablePathAttribute( "video", "poster" ),
|
|
new ResolvablePathAttribute( "video", "src" ),
|
|
new ResolvablePathAttribute( "*", "style" ),
|
|
new ResolvablePathAttribute( "image", "xlink:href" ),
|
|
new ResolvablePathAttribute( "*", "data-load-audio-element" ),
|
|
new ResolvablePathAttribute( "meta", "content" ),
|
|
new ResolvablePathAttribute( "*", "data-root-href" ),
|
|
]
|
|
|
|
private static _rootToken = "::/";
|
|
|
|
static clearRootPath( rootPath:string )
|
|
{
|
|
return rootPath.replace( /^\:\:\//, "" );
|
|
}
|
|
|
|
static isRootPath( path:string )
|
|
{
|
|
return path.startsWith( RootPathResolver._rootToken );
|
|
}
|
|
|
|
|
|
|
|
static get rootToken()
|
|
{
|
|
return RootPathResolver._rootToken;
|
|
}
|
|
|
|
getRootPath( relativeFilePath:string )
|
|
{
|
|
let normalizedPath = relativeFilePath.replace( /\\/g, "/" );
|
|
|
|
if ( normalizedPath.startsWith( "/" ) )
|
|
{
|
|
normalizedPath = normalizedPath.substring( 1 );
|
|
}
|
|
|
|
let numParentDirectories = normalizedPath.split( "/" ).length - 1;
|
|
let rootPath = "";
|
|
|
|
for ( let i = 0; i < numParentDirectories; i++ )
|
|
{
|
|
rootPath += "../";
|
|
}
|
|
|
|
return rootPath;
|
|
}
|
|
|
|
|
|
process( target:Element|Document, relativeFilePath:string )
|
|
{
|
|
let rootPath = this.getRootPath( relativeFilePath );
|
|
|
|
RootPathResolver.resolvables.forEach(
|
|
( resolvable )=>
|
|
{
|
|
let elements = resolvable.getFrom( target );
|
|
|
|
elements.forEach(
|
|
( e:Element ) =>
|
|
resolvable.process( e, RootPathResolver.rootToken, rootPath )
|
|
);
|
|
}
|
|
)
|
|
|
|
RootPathResolver.customResolve.forAll(
|
|
target,
|
|
( e:Element ) =>
|
|
{
|
|
let attName = RootPathResolver.customResolve.from( e );
|
|
let att = new ElementAttribute( attName, false );
|
|
let path = att.from( e );
|
|
|
|
console.log( `Processing custom root path "${attName}" = "${path}"` );
|
|
if ( path === null )
|
|
{
|
|
console.log( "Root Path Resolve: No path found in ", attName);
|
|
return;
|
|
}
|
|
path = path.replace( RootPathResolver.rootToken, rootPath );
|
|
att.to( e, path );
|
|
}
|
|
)
|
|
}
|
|
} |