void HTMLElementImp::setOnclick(html::Function onclick)
{
    DocumentImp* document = getOwnerDocumentImp();
    DocumentWindowPtr window = document->activate();
    addEventListener(u"click",
                     new(std::nothrow) EventListenerImp(boost::bind(&ECMAScriptContext::dispatchEvent, window->getContext(), onclick, _1)));
}
void HTMLObjectElementImp::eval()
{
    HTMLElementImp::eval();
    HTMLElementImp::evalBorder(this);
    HTMLElementImp::evalHeight(this);
    HTMLElementImp::evalWidth(this);
    HTMLElementImp::evalHspace(this);
    HTMLElementImp::evalVspace(this);

    if (!active)
        return;

    std::u16string classid = getAttribute(u"classid");
    if (!classid.empty()) {
        active = false;
        return;
    }
    std::u16string data = getAttribute(u"data");
    if (data.empty()) {
        active = false;
        return;
    }
    std::u16string type = getAttribute(u"type");
    // TODO: Check type is a supported one.

    DocumentImp* document = getOwnerDocumentImp();
    request = new(std::nothrow) HttpRequest(document->getDocumentURI());
    if (request) {
        request->open(u"GET", data);
        request->setHandler(boost::bind(&HTMLObjectElementImp::notify, this));
        document->incrementLoadEventDelayCount();
        request->send();
    } else
        active = false;
}
Ejemplo n.º 3
0
void HTMLStyleElementImp::handleMutation(EventListenerImp* listener, events::Event event)
{
    // TODO: update type, media, and scoped. Then check type.

    events::MutationEvent mutation(interface_cast<events::MutationEvent>(event));

    DocumentImp* document = getOwnerDocumentImp();
    if (!document)
        return;

    if (mutation.getType() == u"DOMNodeRemoved" && event.getTarget().self() == this)
        styleSheet = 0;
    else {
        std::u16string content;
        for (Node node = getFirstChild(); node; node = node.getNextSibling()) {
            if (TextImp* text = dynamic_cast<TextImp*>(node.self()))  // TODO better to avoid imp call?
                content += text->getData();
        }
        CSSParser parser;
        styleSheet = parser.parse(document, content);
        if (auto imp = dynamic_cast<CSSStyleSheetImp*>(styleSheet.self())) {
            imp->setOwnerNode(this);
            if (4 <= getLogLevel())
                dumpStyleSheet(std::cerr, imp);
        }
    }
    if (WindowImp* view = document->getDefaultWindow())
        view->setFlags(Box::NEED_SELECTOR_REMATCHING);
    document->resetStyleSheets();
}
void HTMLElementImp::xblEnteredDocument(Node node)
{
    while (node) {
        if (auto element = dynamic_cast<HTMLElementImp*>(node.self())) {
            if (element->shadowTarget && !element->shadowImplementation) {
                DocumentImp* document = element->getOwnerDocumentImp();
                DocumentWindowPtr window = document->activate();
                ECMAScriptContext* context = window->getContext();
                element->shadowImplementation = context->xblCreateImplementation(element->shadowTarget, element->bindingImplementation, element, element->shadowTree);
                element->shadowImplementation.xblEnteredDocument();
            }
        }
        if (node.hasChildNodes())
            xblEnteredDocument(node.getFirstChild());
        node = node.getNextSibling();
    }
}
Ejemplo n.º 5
0
void HTMLImageElementImp::notify()
{
    if (request->getStatus() != 200)
        active = false;
    else {
        // TODO: Check type
        delete image;
        image = new(std::nothrow) BoxImage;
        if (!image)
            active = false;
        else {
            if (FILE* file = request->openFile()) {
                image->open(file);
                fclose(file);
            }
            if (image->getState() != BoxImage::CompletelyAvailable) {
                active = false;
                delete image;
                image = 0;
            }
        }
    }
    if (Box* box = getBox()) {
        box->setFlags(Box::NEED_REFLOW);
        Box* ancestor = box->getParentBox();
        if (ancestor && !dynamic_cast<Block*>(ancestor)) {
            // Update inline image
            ancestor = ancestor->getParentBox();
            while (ancestor && !dynamic_cast<Block*>(ancestor))
                ancestor = ancestor->getParentBox();
            if (ancestor)
                ancestor->setFlags(Box::NEED_REFLOW);
        }
    }
    DocumentImp* document = getOwnerDocumentImp();
    document->decrementLoadEventDelayCount();
}
void HTMLElementImp::generateShadowContent(CSSStyleDeclarationImp* style)
{
    if (style->binding.getValue() != CSSBindingValueImp::Uri ||
        style->display.getValue() == CSSDisplayValueImp::None)
        return;
    if (getShadowTree())  // already attached?
        return;
    DocumentImp* document = getOwnerDocumentImp();
    assert(document);
    URL base(document->getDocumentURI());
    URL url(base, style->binding.getURL());
    if (!base.isSameExceptFragments(url)) {
        document = dynamic_cast<DocumentImp*>(document->loadBindingDocument(url).self());
        if (!document || document->getReadyState() != u"complete")
            return;
    }

    std::u16string hash = url.getHash();
    if (hash[0] == '#')
        hash.erase(0, 1);
    Element element = document->getElementById(hash);
    if (!element)
        return;
    auto binding = dynamic_cast<HTMLBindingElementImp*>(element.self());
    if (!binding)
        return;
    bindingImplementation = binding->getImplementation();
    if (!bindingImplementation)
        return;
    if (html::HTMLTemplateElement shadowTree = binding->cloneTemplate()) {
        setShadowTree(shadowTree);
        shadowTarget = new(std::nothrow) EventTargetImp;
        // TODO: if (not called from the background thread) {
#if 0
            DocumentWindowPtr window = document->activate();
            ECMAScriptContext* context = window->getContext();
            shadowImplementation = context->xblCreateImplementation(shadowTarget, bindingImplementation, this, shadowTree);
            shadowImplementation .xblEnteredDocument();
        }
#endif
    }
Ejemplo n.º 7
0
bool EventTargetImp::dispatchEvent(events::Event evt)
{
    EventImp* event = dynamic_cast<EventImp*>(evt.self());
    if (!event)
        return false;

    event->setDispatchFlag(true);
    if (auto documentWindow = dynamic_cast<DocumentWindow*>(this))
        event->setTarget(documentWindow->getWindowImp());
    else
        event->setTarget(this);

    if (NodeImp* node = dynamic_cast<NodeImp*>(this)) {
        DocumentImp* document = dynamic_cast<DocumentImp*>(node);
        if (!document)
            document = node->getOwnerDocumentImp();
        assert(document);

        document->enter();

        std::list<EventTargetImp*> eventPath;
        for (NodeImp* ancestor = node->parentNode; ancestor; ancestor = ancestor->parentNode) {
            if (auto shadowTree = dynamic_cast<HTMLTemplateElementImp*>(ancestor)) {
                if (NodeImp* host = dynamic_cast<NodeImp*>(shadowTree->getHost().self())) {
                    // TODO: Fix 'target' of the event as well.
                    // TODO: Check the mouseover and mouseout events.
                    ancestor = host;
                    if (!dynamic_cast<UIEventImp*>(event)) {
                        // To repaint the window, we still need to notify the bound document
                        // of the event.
                        // TODO: Support nesting of bound elements.
                        eventPath.push_front(ancestor->getOwnerDocumentImp());
                        break;
                    }
                }
            }
            eventPath.push_front(ancestor);
        }

        // cf. http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#events-and-the-window-object
        if (document && event->getType() != u"load") {
            if (WindowImp* view = document->getDefaultWindow())
                eventPath.push_front(view->getDocumentWindow().get());
        }

        event->setEventPhase(events::Event::CAPTURING_PHASE);
        for (auto i = eventPath.begin(); i != eventPath.end(); ++i) {
            if (event->getStopPropagationFlag())
                break;
            event->setCurrentTarget(*i);
            (*i)->invoke(event);
        }

        event->setEventPhase(events::Event::AT_TARGET);
        if (!event->getStopPropagationFlag()) {
            event->setCurrentTarget(node);
            node->invoke(event);
        }

        if (event->getBubbles()) {
            event->setEventPhase(events::Event::BUBBLING_PHASE);
            for (auto i = eventPath.rbegin(); i != eventPath.rend(); ++i) {
                if (event->getStopPropagationFlag())
                    break;
                event->setCurrentTarget(*i);
                (*i)->invoke(event);
            }
        }

        if (!event->getDefaultPrevented()) {
            // TODO: Call default actions;
            // cf. http://www.w3.org/TR/DOM-Level-3-Events/#event-flow-default-cancel
            // cf. http://www.w3.org/TR/xbl/#the-default-phase0
            event->setEventPhase(EventImp::DEFAULT_PHASE);
            event->setCurrentTarget(node);
            node->invoke(event);
            if (event->getBubbles()) {
                for (auto i = eventPath.rbegin(); i != eventPath.rend(); ++i) {
                    if (event->getDefaultPrevented())
                        break;
                    event->setCurrentTarget(*i);
                    (*i)->invoke(event);
                }
            }
        }

        document->exit();

    } else if (DocumentWindow* window = dynamic_cast<DocumentWindow*>(this)) {
        auto proxy = dynamic_cast<WindowImp*>(window->getDocument().getDefaultView().self());
        window->enter(proxy);
        event->setEventPhase(events::Event::AT_TARGET);
        event->setCurrentTarget(this);
        invoke(event);
        window->exit(proxy);
    }
    event->setDispatchFlag(false);
    event->setEventPhase(events::Event::AT_TARGET);
    event->setCurrentTarget(0);

    return !event->getDefaultPrevented();
}