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; }
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 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 HTMLMarqueeElementImp::handleMutation(events::MutationEvent mutation) { ECMAScriptContext* context = getOwnerDocumentImp()->getContext(); css::CSSStyleDeclaration style(getStyle()); std::u16string value = mutation.getNewValue(); bool compile = false; if (!value.empty()) { switch (mutation.getAttrChange()) { case events::MutationEvent::MODIFICATION: case events::MutationEvent::ADDITION: compile = true; break; default: break; } } switch (Intern(mutation.getAttrName().c_str())) { // Styles case Intern(u"height"): if (mapToDimension(value = mutation.getNewValue())) style.setProperty(u"height", value, u"non-css"); break; case Intern(u"hspace"): if (mapToDimension(value)) { style.setProperty(u"margin-left", value, u"non-css"); style.setProperty(u"margin-right", value, u"non-css"); } break; case Intern(u"vspace"): if (mapToDimension(value)) { style.setProperty(u"margin-top", value, u"non-css"); style.setProperty(u"margin-bottom", value, u"non-css"); } break; case Intern(u"width"): if (mapToDimension(value = mutation.getNewValue())) style.setProperty(u"width", value, u"non-css"); break; // Event handlers case Intern(u"onbounce"): setOnbounce(compile ? context->compileFunction(value).self() : nullptr); break; case Intern(u"onfinish"): setOnfinish(compile ? context->compileFunction(value).self() : nullptr); break; case Intern(u"onstart"): setOnstart(compile ? context->compileFunction(value).self() : nullptr); break; default: HTMLElementImp::handleMutation(mutation); break; } }
void HTMLImageElementImp::handleMutation(events::MutationEvent mutation) { std::u16string value = mutation.getNewValue(); css::CSSStyleDeclaration style(getStyle()); switch (Intern(mutation.getAttrName().c_str())) { case Intern(u"src"): if (DocumentImp* document = getOwnerDocumentImp()) { if (request) request->abort(); else request = new(std::nothrow) HttpRequest(document->getDocumentURI()); if (request) { request->open(u"GET", getSrc()); request->setHandler(boost::bind(&HTMLImageElementImp::notify, this)); document->incrementLoadEventDelayCount(); request->send(); } else active = false; } break; // Styles case Intern(u"border"): handleMutationBorder(mutation); break; case Intern(u"height"): if (mapToDimension(value)) style.setProperty(u"height", value, u"non-css"); break; case Intern(u"hspace"): if (mapToDimension(value)) { style.setProperty(u"margin-left", value, u"non-css"); style.setProperty(u"margin-right", value, u"non-css"); } break; case Intern(u"vspace"): if (mapToDimension(value)) { style.setProperty(u"margin-top", value, u"non-css"); style.setProperty(u"margin-bottom", value, u"non-css"); } break; case Intern(u"width"): if (mapToDimension(value)) style.setProperty(u"width", value, u"non-css"); break; default: HTMLElementImp::handleMutation(mutation); break; } }
void HTMLElementImp::eval() { DocumentWindowPtr window = getOwnerDocumentImp()->activate(); Nullable<std::u16string> attr = getAttribute(u"style"); if (attr.hasValue()) { CSSParser parser; style = parser.parseDeclarations(attr.value()); parser.getStyleDeclaration()->setOwner(this); } attr = getAttribute(u"onclick"); if (attr.hasValue()) setOnclick(window->getContext()->compileFunction(attr.value())); attr = getAttribute(u"onload"); if (attr.hasValue()) setOnload(window->getContext()->compileFunction(attr.value())); }
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 }
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(); }
html::HTMLElement HTMLTableRowElementImp::insertCell(int index) { if (index < -1) return 0; // TODO: throw an IndexSizeError exception int count = 0; for (Element child = getFirstElementChild(); child; child = child.getNextElementSibling()) { if (HTMLTableCellElementImp* cell = dynamic_cast<HTMLTableCellElementImp*>(child.self())) { if (count == index) { html::HTMLTableDataCellElement td = new(std::nothrow) HTMLTableDataCellElementImp(getOwnerDocumentImp()); if (td) insertBefore(td, cell); return td; } ++count; } } if (count < index) return 0; // TODO: throw an IndexSizeError exception html::HTMLTableDataCellElement td = new(std::nothrow) HTMLTableDataCellElementImp(getOwnerDocumentImp()); if (td) appendChild(td); return td; }
html::HTMLElement HTMLTableRowElementImp::insertCell(int index) { if (index < -1) return nullptr; // TODO: throw an IndexSizeError exception int count = 0; for (Element child = getFirstElementChild(); child; child = child.getNextElementSibling()) { if (auto cell = std::dynamic_pointer_cast<HTMLTableCellElementImp>(child.self())) { if (count == index) { html::HTMLTableDataCellElement td = std::make_shared<HTMLTableDataCellElementImp>(getOwnerDocumentImp().get()); if (td) insertBefore(td, cell); return td; } ++count; } } if (count < index) return nullptr; // TODO: throw an IndexSizeError exception html::HTMLTableDataCellElement td = std::make_shared<HTMLTableDataCellElementImp>(getOwnerDocumentImp().get()); if (td) appendChild(td); return td; }