WIP: Shadow DOM
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ApiClient from "api/Client"
|
||||
import Modal, { Content } from "components/Modal"
|
||||
import Modal from "components/Modal"
|
||||
import InvalidConfigurationError from "components/InvalidConfigurationError"
|
||||
import Form from "components/Form"
|
||||
import Spinner from "components/Spinner"
|
||||
@@ -160,6 +160,7 @@ class Bubble extends Component {
|
||||
// EVENT HANDLERS -----------------------------------------------------------
|
||||
|
||||
handleKeyDown = event => {
|
||||
event.stopPropagation()
|
||||
if (event.keyCode === 27) {
|
||||
this.close()
|
||||
}
|
||||
@@ -223,19 +224,18 @@ class Bubble extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="moco-bx-bubble">
|
||||
<img
|
||||
onClick={this.open}
|
||||
src={chrome.extension.getURL(logoUrl)}
|
||||
width="50%"
|
||||
/>
|
||||
{this.bookedHours > 0 && <span className="booked-hours"><small>{this.bookedHours}h</small></span>}
|
||||
{this.isOpen && (
|
||||
<Modal>
|
||||
<Content>{this.renderContent()}</Content>
|
||||
{this.renderContent()}
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { Component } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
class Modal extends Component {
|
||||
@@ -7,35 +6,17 @@ class Modal extends Component {
|
||||
children: PropTypes.node.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.el = document.createElement("div")
|
||||
this.el.setAttribute("class", "moco-bx-modal")
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const modalRoot = document.getElementById("moco-bx-container")
|
||||
modalRoot.appendChild(this.el)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const modalRoot = document.getElementById("moco-bx-container")
|
||||
modalRoot.removeChild(this.el)
|
||||
}
|
||||
|
||||
// RENDER -------------------------------------------------------------------
|
||||
|
||||
render() {
|
||||
return createPortal(this.props.children, this.el)
|
||||
return (
|
||||
<div className="moco-bx-modal">
|
||||
<div className="moco-bx-modal-content">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function Content({ children }) {
|
||||
return <div className="moco-bx-modal-content">{children}</div>
|
||||
}
|
||||
|
||||
Content.propTypes = {
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
export default Modal
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
flatMap,
|
||||
pathEq
|
||||
} from "lodash/fp"
|
||||
import { trace } from "utils"
|
||||
|
||||
const customTheme = theme => ({
|
||||
...theme,
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
const Spinner = () => (
|
||||
<div className="spinner" role="status">
|
||||
<span className="sr-only">Loading...</span>
|
||||
</div>
|
||||
<div className="moco-bx-spinner" role="status" />
|
||||
)
|
||||
|
||||
export default Spinner
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { createElement } from "react"
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom"
|
||||
import ShadowDOM from "react-shadow"
|
||||
import Bubble from "./components/Bubble"
|
||||
import services from "remoteServices"
|
||||
import { parseServices, createMatcher, createEnhancer } from "utils/urlMatcher"
|
||||
import { createMatcher, createEnhancer } from "utils/urlMatcher"
|
||||
import remoteServices from "./remoteServices"
|
||||
import { pipe } from 'lodash/fp'
|
||||
import "../css/main.scss"
|
||||
import "../css/content.scss"
|
||||
|
||||
const matcher = createMatcher(remoteServices)
|
||||
const serviceEnhancer = createEnhancer(window.document)
|
||||
@@ -32,35 +32,27 @@ const mountBubble = (settings) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (!document.getElementById("moco-bx-container")) {
|
||||
const domContainer = document.createElement("div")
|
||||
domContainer.setAttribute("id", "moco-bx-container")
|
||||
document.body.appendChild(domContainer)
|
||||
}
|
||||
|
||||
if (!document.getElementById("moco-bx-bubble")) {
|
||||
const domBubble = document.createElement("div")
|
||||
domBubble.setAttribute("id", "moco-bx-bubble")
|
||||
document.body.appendChild(domBubble)
|
||||
if (!document.getElementById("moco-bx-root")) {
|
||||
const domRoot = document.createElement("div")
|
||||
domRoot.setAttribute("id", "moco-bx-root")
|
||||
document.body.appendChild(domRoot)
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
createElement(Bubble, { service, settings }),
|
||||
document.getElementById("moco-bx-bubble")
|
||||
<ShadowDOM include={[chrome.extension.getURL('content.css')]}>
|
||||
<div>
|
||||
<Bubble service={service} settings={settings} />
|
||||
</div>
|
||||
</ShadowDOM>,
|
||||
document.getElementById("moco-bx-root")
|
||||
)
|
||||
}
|
||||
|
||||
const unmountBubble = () => {
|
||||
const domBubble = document.getElementById("moco-bx-bubble")
|
||||
const domContainer = document.getElementById("moco-bx-container")
|
||||
const domRoot = document.getElementById("moco-bx-root")
|
||||
|
||||
if (domBubble) {
|
||||
ReactDOM.unmountComponentAtNode(domBubble)
|
||||
domBubble.remove()
|
||||
}
|
||||
|
||||
if (domContainer) {
|
||||
ReactDOM.unmountComponentAtNode(domContainer)
|
||||
domContainer.remove()
|
||||
if (domRoot) {
|
||||
ReactDOM.unmountComponentAtNode(domRoot)
|
||||
domRoot.remove()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createElement } from "react"
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom"
|
||||
import Setup from "./components/Setup"
|
||||
import "../css/main.scss"
|
||||
import "../css/options.scss"
|
||||
|
||||
const domContainer = document.querySelector("#moco-bx-container")
|
||||
ReactDOM.render(createElement(Setup), domContainer)
|
||||
const domContainer = document.querySelector("#moco-bx-root")
|
||||
ReactDOM.render(<Setup />, domContainer)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { createElement } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import Form from './components/Form'
|
||||
|
||||
const domContainer = document.querySelector('#moco-bx-container')
|
||||
ReactDOM.render(createElement(Form, {inline: false}), domContainer)
|
||||
@@ -25,6 +25,12 @@ export default {
|
||||
description: (document, service, { org, repo, id }) =>
|
||||
`${org}/${repo}/${id} - ${document
|
||||
.querySelector(".gh-header-title")
|
||||
.textContent.trim()}`
|
||||
.textContent.trim()}`,
|
||||
},
|
||||
|
||||
"trello": {
|
||||
name: "trello",
|
||||
urlPattern: "https://trello.com/c/:id/:title",
|
||||
description: (document, service, { title }) => title.split('-').slice(1).join(' ')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user