# DOM, CSS e sandbox

Distinga propriedade do DOM, isolamento de estilos e realm JavaScript sem confundi-los com uma fronteira de segurança.

<span id="tres-decisiones-distintas"></span>

<span class="section-anchor" id="section-1"></span>

## Três decisões diferentes

O comportamento de uma app depende de **onde o JavaScript é executado**, **quem é responsável pelo limite DOM** e **quais estilos recebe**. Configurar uma dessas dimensões não configura automaticamente as outras.

| Modo JavaScript | Execução | Uso e limites |
| --- | --- | --- |
| `module` | `import()` na janela principal | Módulos modernos confiáveis; não isola globais do host |
| `strict` | Import real dentro de iframe oculto | Realm separado e limpeza; requer que o módulo possa ser carregado ali |
| `eval` | Caminho de HTML/scripts clássicos dentro de iframe | Compatibilidade com UMD/IIFE; não aceita módulos ESM como strict |

O modo `eval` executa scripts no iframe pelo caminho de compatibilidade HTML; para módulos ESM, use `module` ou `strict` conforme o realm necessário.

<span id="strict-y-su-fallback"></span>

<span class="section-anchor" id="section-2"></span>

## Strict e seu fallback

```js
await wu.init({
  sandbox: 'strict',
  strictFallback: false,
  apps: [{ name: 'reports', url: '/apps/reports' }],
});

await wu.mount('reports', '#reports-slot');
console.table(wu.getSandboxInfo('reports'));
```

Uma falha de import dentro do iframe produz erro por padrão. `strictFallback: true` autoriza explicitamente uma degradação para o modo eval; não corrige um bundle ESM incompatível com esse modo. A opção por aplicação prevalece sobre a global.

`getSandboxInfo` expõe `requestedMode`, `actualMode`, `isolationLevel`, `mounted`, `nativeShadow` e `domOwnership`. Compare requestedMode e actualMode ao diagnosticar um fallback: a configuração expressa a preferência e o estado descreve o modo que executa essa app.

<span id="quién-posee-el-dom"></span>

<span class="section-anchor" id="section-3"></span>

## Quem é responsável pelo DOM

| `domOwnership` | Resultado |
| --- | --- |
| `wu` | O WU cria o ShadowRoot externo e entrega uma raiz interna ao renderizador |
| `app` | O renderizador gerencia seu próprio limite, útil para LitElement |
| `light` | Montagem sem o ShadowRoot externo do WU |

O valor explícito prevalece. Na sua ausência, `nativeShadow: true` seleciona `app`, `false` seleciona `wu`; sem ambos, `framework: 'lit'` seleciona `app` e os demais, `wu`.

O nome `app` expressa uma responsabilidade, não uma garantia de que o componente realmente crie Shadow DOM. Se o renderizador não criar seu próprio limite, o conteúdo permanece na árvore DOM recebida.

<span id="distribución-de-estilos"></span>

<span class="section-anchor" id="section-4"></span>

## Distribuição de estilos

Configure o manifesto da aplicação:

```json
{
  "name": "reports",
  "entry": "assets/reports.js",
  "styleMode": "own-only"
}
```

| Valor | Significado |
| --- | --- |
| `shared` | A ponte permite a distribuição de estilos externos no ShadowRoot |
| `isolated` / `none` | Não injeta estilos externos adicionais |
| `fully-isolated` / `own-only` | Injeta os identificados como pertencentes a essa app |

A ponte observa alterações e atribui estilos às aplicações. Para uma folha criada por código do host, existe `wu.tagStyleAsApp(element, appName)`. Não pressuponha que uma regra CSS global do shell atravesse um ShadowRoot. Custom properties herdadas e propriedades CSS herdáveis podem continuar participando da aparência do conteúdo.

O sandbox recebe `styleMode` do manifesto. Coloque ali a decisão de estilos; o campo de mesmo nome na configuração superior do host não substitui esse valor durante a montagem.

<span id="la-frontera-de-confianza-real"></span>

<span class="section-anchor" id="section-5"></span>

## A fronteira de confiança real

O próprio iframe documenta que é da mesma origem e redireciona a criação de nós ao documento do host. Um nó pode expor `ownerDocument.defaultView`, de onde um script alcança o host. Ocultar `parent` ou `top` não fecha essa via.

Use esses modos para coordenar código confiável, globais e limpeza. Para executar código não confiável, você precisa de outra fronteira, como uma origem isolada e um protocolo restrito; os iframes da mesma origem do runtime mantêm acesso potencial ao host.

<span id="contenedores-y-layout"></span>

<span class="section-anchor" id="section-6"></span>

## Contêineres e layout

Um slot deve ser território exclusivo do renderizador. No React/Vue, coloque a mensagem de carregamento como irmã do nó de montagem: se o shell reconciliar seus filhos dentro do mesmo nó, pode apagar a árvore inserida pelo WU. O teste específico de Vue do repositório reproduz essa falha silenciosa.

`fullBleed` na configuração do host decide se o microfrontend ocupa a altura do slot e assume a responsabilidade por sua rolagem. Se o conteúdo deve fluir com o documento, mantenha o comportamento padrão. A altura do slot e seu layout continuam sendo responsabilidade do shell.

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-7"></span>

## Referência de implementação

Modos: `src/core/wu-core.js`, `src/core/wu-core.js`, `src/core/wu-core.js`, `src/core/wu-core.js`; propriedade: `src/core/wu-sandbox.js`; limite de mesma origem: `src/core/wu-iframe-sandbox.js`. Testes: `tests/unit/sandbox-honesty.test.js`, `tests/unit/native-shadow-sandbox.test.js`, `tests/unit/sandbox-container-ownership.test.js`, `tests/unit/style-own-only.test.js`, `tests/unit/style-cross-app.test.js`, `tests/unit/vue-slot-mount-target.test.js`.

Em `strict`, `parent.postMessage` respeita `targetOrigin` e entrega a janela do sandbox como `event.source`. O acesso interno `__wuHostPostMessage` foi removido. Essa correção de identidade não transforma o iframe de mesma origem em isolamento contra código hostil.