First commit

This commit is contained in:
2025-12-25 11:16:59 +01:00
commit 0c5ca09a63
720 changed files with 329234 additions and 0 deletions

637
framework/client/css.js Normal file
View File

@@ -0,0 +1,637 @@
/*
Copyright (c) 2020, 2023, The Unified Company.
This code is part of Unify.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE,
as published by the Free Software Foundation.
See the GNU AFFERO GENERAL PUBLIC LICENSE, for more details.
https://unifyjs.org
*/
import cssRules from './cssRules.js';
import document from '../unify/document.js';
import cssManager from './cssManager.js';
import tools from '../unify/tools.js';
import definitions from '../unify/definitions.js';
export default class css{
cssCache = new cssManager();
global_css = "";
skipBoxTerms = new Array( "box-sizing", "box-shadow", "box-reflect", "box-decoration-break" );
constructor() {
this.boxTermWithoutPrefix = new Array();
for (var i = 0; i < this.skipBoxTerms.length; i++) {
var boxTerm = this.skipBoxTerms[i]
this.boxTermWithoutPrefix[i] = boxTerm.replace("box-")
}
}
PerformPropertyGridCorrection( property ) {
for ( var i = 0; i < this.skipBoxTerms.length; i++ ) {
if( this.boxTermWithoutPrefix[ i ].includes( property ) ) {
property = this.skipBoxTerms[ i ];
}
}
return property;
}
parseObject( object ){
var objectName = object.propertyName;
object.__proto__.css = new cssRules();
object.__proto__.boxRules = new cssRules();
object.__proto__.cssRules = new cssRules();
object.cssRules.addStyleListener( "hover", ":hover" );
object.cssRules.addStyleListener( "visited", ":visited" );
object.cssRules.addStyleListener( "link", ":link" );
object.cssRules.addStyleListener( "active", ":active" );
object.cssRules.addStyleListener( "placeholder", "::placeholder" );
object.cssRules.addStyleListener( "scrollbar", "::-webkit-scrollbar" );
object.cssRules.addStyleListener( "scrollbarTrack", "::-webkit-scrollbar-track" );
object.cssRules.addStyleListener( "scrollbarThumb", "::-webkit-scrollbar-thumb" );
object.cssRules.addStyleListener( "scrollbarThumbHover", "::-webkit-scrollbar-thumb:hover" );
}
parseCSSValue( value ) {
if( typeof value == "number" ) {
value += "px";
}
return value;
}
createStyleRule( normalizedProperty, value ){
if( !value ) {
return "";
}
value = this.parseCSSValue( value );
normalizedProperty = this.PerformPropertyGridCorrection( normalizedProperty );
return "\t" + normalizedProperty + ":" + value + "; \n";
}
compareUpperCase( term ) {
const compare = function( current ){ if( term.indexOf( current ) != -1 ){ return true; } }
const n = definitions.alphabet;
var map = n.map( compare );
return map; // [false, false, true, false] where true is where higher case is
}
hasUpperCase( a ) {
let regExp = /[A-Z]/;
return regExp.test( a );
}
replaceUpperCase( word ) {
var map = this.compareUpperCase( word );
var letter = definitions.alphabet[ map.indexOf( true ) ];
return word.replace( letter, "-" + letter.toLowerCase() );
}
normalizePropertyName( name ) {
return tools.firstLowerCase( name.replace("__", "").replace("box", "") );
}
// needs caching
normalizeProperty( name ) {
// webkit -> -webkit
if( name.slice( 0, 6 ) == "webkit" ) {
name = "-" + name;
}
for (var i = 0; i < 6; i++) {
if( this.hasUpperCase( name ) ) {
name = this.replaceUpperCase( name ); // backgroundColor -> background-color-and-something
}
}
return name;
}
setter( object, domStyleObject, propertyName, property, value ) {
object[ "__" + propertyName ] = value;
value = this.parseCSSValue( value );
property = this.PerformPropertyGridCorrection( property );
var NSTabNames = new Array("svg", "circle")
// todo : doesnt work properly
//if( NSTabNames.includes( object.element.tagName ) ) {
// domStyleObject.setAttributeNS( null, property, value );
//} else {
domStyleObject.setProperty( property, value );
//}
}
createSetter( property, objectProperty, object, domStyleObject ) {
var css = this;
object[ "__" + objectProperty ] = object[ objectProperty ];
object.__defineSetter__( objectProperty, this.setter.bind( this, object, domStyleObject, objectProperty, property ) );
}
getter( object, objectProperty, value ) {
var newValue = object[ "__" + objectProperty ];
if(typeof newValue == "string") {
var chars = newValue.split();
if( chars[chars.length-2] == "p" && chars[chars.length-1] == "x" ) {
chars = chars.slice(0, -2);
newValue = chars.join();
}
}
if( tools.isCustomNumber( newValue ) ) {
return parseFloat( newValue );
} else {
return newValue;
}
}
createGetter( property, objectProperty, object, domStyleObject ) {
object.__defineGetter__( objectProperty, this.getter.bind( this, object, objectProperty ) );
}
parseProperty( property, object ) {
var propertyName = property.name;
var propertyValue = property.value;
var normalizedProperty = this.normalizeProperty( propertyName );
//if( propertyName == "gridArea" && propertyValue == "none" ) {
// return false;
//}
var slicedProperty = propertyName.toLowerCase().slice( 0, 3 );
if( slicedProperty == "box" ) {
object.boxRules.style += this.parseCssTerm( object, propertyName, propertyValue, object.elements[0], "box" );
} else {
object.css.style += this.parseCssTerm( object, propertyName, propertyValue, object.element )
}
this.parseExtraStyleSuffixes( object, propertyName, propertyValue );
}
parseExtraStyleSuffixes( object, propertyName, propertyValue ) {
var styleTypes = object.cssRules.styleTypes;
for ( var i = 0; i < styleTypes.length; i++ ) {
var cssType = styleTypes[i];
var propertyTerm = cssType.propertyTerm;
var slicedProperty = propertyName.slice( 0, propertyTerm.length );
if( slicedProperty == propertyTerm && propertyName.length > slicedProperty.length ) {
cssType.css += this.parseCssTerm( object, propertyName, propertyValue, object.elements[0], propertyTerm );
}
}
}
parseCssTerm( object, propertyName, propertyValue, element, term = "" ) {
var cssPropertyName = tools.firstLowerCase( propertyName.replace( term, "" ) );
var normalizedProperty = this.normalizeProperty( cssPropertyName );
if( this.propertyIsStyle( normalizedProperty ) ) {
// Setters and getters don't work yet for special suffixes.
if( !term || term == "box" ) {
this.createSetter( normalizedProperty, propertyName, object, element.style );
this.createGetter( normalizedProperty, propertyName, object, element.style );
}
return this.createStyleRule( normalizedProperty, propertyValue );
} else {
return "";
}
}
clearCache() {
this.cssCache.rules = new Array();
}
parseCssRule( object, objectPropertyName, propertyName, propertyValue ) {
var normalizedProperty = this.normalizeProperty( objectPropertyName );
object.boxRules.style += this.createStyleRule( normalizedProperty, propertyValue );
this.createSetter( objectPropertyName, propertyName, object, object.elements[0].style );
this.createGetter( objectPropertyName, propertyName, object, object.elements[0].style );
}
createSelector( className, afterTerm ) {
var selector = "." + className;
selector += "." + this.device;
selector += "." + this.os;
selector += "." + this.tint;
// this doesnt work yet.
if( afterTerm ) {
selector += afterTerm;
}
//selector += "," + selector.replace( "_" + id, "" );
return selector;
}
createStyleSheet( object ){
var objectName = tools.createCSSClassName( object );
var body = object.css.style;
if( object.customElement ) {
var selector = this.createSelector( objectName + "Element" );
this.global_css += this.cssCache.getRule( selector, body );
var selector = this.createSelector( objectName + "Grid" );
this.global_css += this.cssCache.getRule( selector, body );
} else {
var selector = this.createSelector( objectName + "Grid" );
this.global_css += this.cssCache.getRule( selector, body );
}
if( object.boxRules ) {
var selector = this.createSelector( objectName + "Box" );
var body = object.boxRules.style;
this.global_css += this.cssCache.getRule( selector, body );
}
var styleTypes = object.cssRules.styleTypes;
for (var i = 0; i < styleTypes.length; i++) {
var cssType = styleTypes[i];
if( object.useCustomElement ) {
var selector = this.createSelector( objectName + "Element", cssType.cssSuffix );
} else {
var selector = this.createSelector( objectName + "Grid", cssType.cssSuffix );
}
var body = cssType.css;
if( body != "" ) {
//console.log("cssType.cssSuffix", cssType.cssSuffix);
this.global_css += this.cssCache.getRule( selector, body );
}
}
if( !object.parent ) {
this.writeCssToPage( this.global_css );
this.global_css = "";
}
if( object.dynamic ) {
this.writeCssToPage( this.global_css );
this.global_css = "";
}
}
writeCssToPage( css ) {
if( css == "" ) {
return false;
}
var style = document.createElement("style");
style.innerHTML = css;
document.head.appendChild( style );
}
removeStripe( name ) {
var splitName = name.split("-");
if( splitName.length > 1 ) {
return splitName[1].toLowerCase();
} else {
return name;
}
}
getStyleSheetObject(){
if( !document.body ) {
return definitions.css;
/*
var array = JSON.parse(cssDef);
var object = new Object();
for (var i = 0; i < array.length; i++) {
var def = array[i];
if( this.hasUpperCase( def ) ) {
object[ this.replaceUpperCase( def ) ] = '';
console.log( this.replaceUpperCase( def ) );
} else {
object[ def ] = '';
}
}
*/
return object;
}
if( document.body.style ) {
var bodyStyle = document.body.style;
bodyStyle.webkitBoxShadow = "";
return bodyStyle;
}
if( document.body.styleSheets ) {
// fix please!!!! not allowed
return document.styleSheets[1].cssRules[0].style;
} else {
return document.customStyleTerms;
}
}
camelCaseToDash( name ) {
for ( var i = 0; i < 4; i++ ) {
if( this.hasUpperCase( name ) ) {
name = this.replaceUpperCase( name ); // backgroundColor -> background-color
}
}
return name;
}
removeBoxPrefix( name ) {
if( !name.includes("webkit-box") ) {
name = name.replace("box", "").toLowerCase();
}
return name;
}
checkBoxSpecialCase( name ) {
for (var i = 0; i < this.boxTermWithoutPrefix.length; i++) {
if( this.boxTermWithoutPrefix[ i ].includes( name ) ) {
return true;
}
}
}
propertyIsStyle( name ){
name = this.camelCaseToDash( name );
name = this.removeBoxPrefix( name );
if( this.checkBoxSpecialCase( name ) ) {
return true;
}
var styleTerms = this.getStyleSheetObject();
if( typeof styleTerms[ name ] == "string" ) {
return true;
} else {
return false;
}
}
propertyHasStyle( name ){
var styleTerms = Object.keys( definitions.css );
if( styleTerms.includes( name.toLowerCase() ) ) {
return true;
} else {
return false;
}
}
}