Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,137 changes: 1,051 additions & 86 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"build": "node scripts/update-build-type.js free && node scripts/sync-version.js ${npm_config_suffix} && npx wp-scripts build && npm run build:css && npm run build:frontend-php && npm run optimize-videos && BUILD_TYPE=free npm run package ${npm_config_suffix}",
"build:frontend-php": "node scripts/generate-frontend-php-scripts.mjs production free",
"build:frontend-php:premium": "node scripts/generate-frontend-php-scripts.mjs production premium",
"build:css": "webpack --config webpack.css.config.js && npm run clean:css-js",
"build:css": "webpack --config webpack.css.config.js && npm run build:css:wp-components-scoped && npm run clean:css-js",
"build:css:wp-components-scoped": "node scripts/build-scoped-wp-components-css.mjs",
"clean:css-js": "rm -f dist/*.css.js",
"start": "node scripts/update-build-type.js free && concurrently \"wp-scripts start\" \"webpack --config webpack.css.config.js --watch\"",
"lint:js": "wp-scripts lint-js",
Expand All @@ -25,7 +26,7 @@
"optimize-videos": "node scripts/optimize-videos.js",
"package": "node scripts/package.js",
"sync-version": "node scripts/sync-version.js",
"build:premium": "node scripts/update-build-type.js premium && node scripts/sync-version.js ${npm_config_suffix} && npm run clean:css-js && npx wp-scripts build --config pro__premium_only/webpack.config.js && npx webpack --config pro__premium_only/webpack.css.config.js && npm run build:frontend-php:premium && npm run optimize-videos && BUILD_TYPE=premium npm run package ${npm_config_suffix}",
"build:premium": "node scripts/update-build-type.js premium && node scripts/sync-version.js ${npm_config_suffix} && npm run clean:css-js && npx wp-scripts build --config pro__premium_only/webpack.config.js && npx webpack --config pro__premium_only/webpack.css.config.js && npm run build:css:wp-components-scoped && npm run build:frontend-php:premium && npm run optimize-videos && BUILD_TYPE=premium npm run package ${npm_config_suffix}",
"start:premium": "cd pro__premium_only && npm run start",
"lint:premium": "cd pro__premium_only && npm run lint",
"lint:premium:fix": "cd pro__premium_only && npm run lint:fix"
Expand All @@ -34,28 +35,29 @@
"extends @wordpress/browserslist-config"
],
"devDependencies": {
"@node-minify/core": "^8.0.6",
"@node-minify/uglify-js": "^8.0.6",
"@svgr/webpack": "^8.1.0",
"@wordpress/babel-preset-default": "^8.19.0",
"@wordpress/eslint-plugin": "^22.15.0",
"@wordpress/prettier-config": "^4.29.0",
"@wordpress/scripts": "^30.0.0",
"@wordpress/stylelint-config": "^23.21.0",
"@wordpress/babel-preset-default": "^8.19.0",
"@svgr/webpack": "^8.1.0",
"@node-minify/core": "^8.0.6",
"@node-minify/uglify-js": "^8.0.6",
"archiver": "^6.0.1",
"babel-loader": "^9.2.1",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint-plugin-compat": "^6.0.2",
"file-loader": "^6.2.0",
"fluent-ffmpeg": "^2.1.3",
"mini-css-extract-plugin": "^2.7.6",
"prettier": "^3.3.3",
"sass": "^1.69.0",
"sass-loader": "^14.0.0",
"style-loader": "^3.3.3",
"archiver": "^6.0.1",
"eslint": "^8.57.0",
"eslint-plugin-compat": "^6.0.2",
"prettier": "^3.3.3"
"style-loader": "^3.3.3"
},
"dependencies": {
"@wordpress/components": "^33.0.0",
"@wordpress/icons": "^10.31.0",
"canvas-confetti": "^1.9.3",
"classnames": "^2.5.1",
Expand Down
101 changes: 101 additions & 0 deletions scripts/build-scoped-wp-components-css.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import fs from 'fs'
import path from 'path'
import postcss from 'postcss'

const ROOT = process.cwd()
const INPUT_CSS = path.join(
ROOT,
'node_modules',
'@wordpress',
'components',
'build-style',
'style.css'
)
const OUTPUT_CSS = path.join( ROOT, 'dist', 'wp-components-scoped.css' )

const COMPONENT_SCOPES = [
'#interact-elementor-root',
'.interact-popover',
]
const BODY_SCOPE = 'body.interact-elementor-editor'
const PORTAL_PATTERNS = [
'.components-modal',
'.components-snackbar',
'.components-tooltip',
'.components-guide',
]

// Wrap scope selectors in :where() so scoping does not increase specificity.
const wrapScope = scope => `:where(${ scope })`

// Some WordPress component UI is rendered in portals outside our sidebar root.
const isPortalSelector = selector => {
return PORTAL_PATTERNS.some( pattern => selector.includes( pattern ) )
}

// Check if a rule is inside a keyframes block, which should not be scoped.
const isInsideKeyframes = rule => {
let current = rule.parent
while ( current ) {
if ( current.type === 'atrule' && current.name.includes( 'keyframes' ) ) {
return true
}
current = current.parent
}
return false
}

// Scope each selector to the Interactions Elementor UI while keeping popovers
// and other portal-based components reachable outside the sidebar root.
const scopeRootSelector = selector => {
if ( selector.startsWith( ':root' ) ) {
return [ ...COMPONENT_SCOPES.map( wrapScope ), wrapScope( BODY_SCOPE ) ]
}

if ( selector.startsWith( 'body' ) ) {
return [ selector.replace( /^body\b/, wrapScope( BODY_SCOPE ) ) ]
}

if ( selector.startsWith( 'html' ) ) {
return [ `${ wrapScope( BODY_SCOPE ) } ${ selector }` ]
}

if ( isPortalSelector( selector ) ) {
return [ `${ wrapScope( BODY_SCOPE ) } ${ selector }` ]
}

if ( /(^|[\s>+~])\.components-popover(?![a-zA-Z0-9_-])/.test( selector ) ) {
return [ selector.replace( /(^|[\s>+~])\.components-popover(?![a-zA-Z0-9_-])/g, `$1${ wrapScope( '.interact-popover.components-popover' ) }` ) ]
}

return COMPONENT_SCOPES.map( scope => `${ wrapScope( scope ) } ${ selector }` )
}

const css = fs.readFileSync( INPUT_CSS, 'utf8' )
const root = postcss.parse( css )

root.walkRules( rule => {
if ( ! Array.isArray( rule.selectors ) ) {
return
}

if ( isInsideKeyframes( rule ) ) {
return
}

rule.selectors = rule.selectors.flatMap( selector => scopeRootSelector( selector ) )
} )

fs.mkdirSync( path.dirname( OUTPUT_CSS ), { recursive: true } )
fs.writeFileSync( OUTPUT_CSS, root.toString() )

process.stdout.write(
JSON.stringify(
{
input: path.relative( ROOT, INPUT_CSS ),
output: path.relative( ROOT, OUTPUT_CSS ),
},
null,
2
) + '\n'
)
Loading
Loading