User AuthModel::processAuthToken() { WApplication *app = WApplication::instance(); const WEnvironment& env = app->environment(); if (baseAuth()->authTokensEnabled()) { const std::string *token = env.getCookie(baseAuth()->authTokenCookieName()); if (token) { AuthTokenResult result = baseAuth()->processAuthToken(*token, users()); switch(result.state()) { case AuthTokenState::Valid: { if (!result.newToken().empty()) { /* * Only extend the validity from what we had currently. */ app->setCookie(baseAuth()->authTokenCookieName(), result.newToken(), result.newTokenValidity(), "", "", app->environment().urlScheme() == "https"); } return result.user(); } case AuthTokenState::Invalid: app->setCookie(baseAuth()->authTokenCookieName(),std::string(), 0, "", "", app->environment().urlScheme() == "https"); return User(); } } } return User(); }
WDialog::DialogCode WDialog::exec(const WAnimation& animation) { if (recursiveEventLoop_) throw WException("WDialog::exec(): already being executed."); animateShow(animation); #ifdef WT_TARGET_JAVA if (!WebController::isAsyncSupported()) throw WException("WDialog#exec() requires a Servlet 3.0 enabled servlet " "container and an application with async-supported " "enabled."); #endif WApplication *app = WApplication::instance(); recursiveEventLoop_ = true; if (app->environment().isTest()) { app->environment().dialogExecuted().emit(this); if (recursiveEventLoop_) throw WException("Test case must close dialog"); } else { do { app->session()->doRecursiveEventLoop(); } while (recursiveEventLoop_); } hide(); return result_; }
WDefaultLoadingIndicator::WDefaultLoadingIndicator() { setImplementation(std::unique_ptr<WWidget> (new WText(tr("Wt.WDefaultLoadingIndicator.Loading")))); setInline(false); setStyleClass("Wt-loading"); WApplication *app = WApplication::instance(); app->styleSheet().addRule("div.Wt-loading", "background-color: red; color: white;" "font-family: Arial,Helvetica,sans-serif;" "font-size: small;" "position: absolute; right: 0px; top: 0px;"); app->styleSheet().addRule("body div > div.Wt-loading", "position: fixed;"); if (app->environment().userAgent().find("MSIE 5.5") != std::string::npos || app->environment().userAgent().find("MSIE 6") != std::string::npos) app->styleSheet().addRule ("div.Wt-loading", "right: expression(((" "ignoreMe2 = document.documentElement.scrollLeft ? " "document.documentElement.scrollLeft : " "document.body.scrollLeft )) + 'px' );" "top: expression(((" "ignoreMe = document.documentElement.scrollTop ? " "document.documentElement.scrollTop : " "document.body.scrollTop)) + 'px' );"); }
WWidget *WItemDelegate::createEditor(const WModelIndex& index, WFlags<ViewItemRenderFlag> flags) const { IndexContainerWidget *const result = new IndexContainerWidget(index); result->setSelectable(true); WLineEdit *lineEdit = new WLineEdit(); lineEdit->setText(asString(index.data(EditRole), textFormat_)); lineEdit->enterPressed().connect (boost::bind(&WItemDelegate::doCloseEditor, this, result, true)); lineEdit->escapePressed().connect (boost::bind(&WItemDelegate::doCloseEditor, this, result, false)); lineEdit->escapePressed().preventPropagation(); if (flags & RenderFocused) lineEdit->setFocus(true); // We use a layout so that the line edit fills the entire cell. // Somehow, this does not work with konqueror, but it does respond // properly to width, height being set to 100% ! WApplication *app = WApplication::instance(); if (app->environment().agent() != WEnvironment::Konqueror) { result->setLayout(new WHBoxLayout()); result->layout()->setContentsMargins(1, 1, 1, 1); result->layout()->addWidget(lineEdit); } else { lineEdit->resize(WLength(100, WLength::Percentage), WLength(100, WLength::Percentage)); result->addWidget(lineEdit); } return result; }
void WTextEdit::initTinyMCE() { const char *THIS_JS = "js/WTextEdit.js"; WApplication *app = WApplication::instance(); if (!app->javaScriptLoaded(THIS_JS)) { if (app->environment().ajax()) app->doJavaScript("window.tinyMCE_GZ = { loaded: true };", false); int version = getTinyMCEVersion(); std::string folder = version == 3 ? "tiny_mce/" : "tinymce/"; std::string jsFile = version == 3 ? "tiny_mce.js" : "tinymce.js"; std::string tinyMCEBaseURL = WApplication::relativeResourcesUrl() + folder; WApplication::readConfigurationProperty("tinyMCEBaseURL", tinyMCEBaseURL); if (!tinyMCEBaseURL.empty() && tinyMCEBaseURL[tinyMCEBaseURL.length()-1] != '/') tinyMCEBaseURL += '/'; app->require(tinyMCEBaseURL + jsFile, "window['tinyMCE']"); app->styleSheet().addRule(".mceEditor", "display: block; position: absolute;"); LOAD_JAVASCRIPT(app, THIS_JS, "WTextEdit", wtjs1); } }
void WFormWidget::setEmptyText(const WString& emptyText) { emptyText_ = emptyText; WApplication* app = WApplication::instance(); const WEnvironment& env = app->environment(); if (env.ajax()) { if (!emptyText_.empty()) { if (!flags_.test(BIT_JS_OBJECT)) defineJavaScript(); else updateEmptyText(); if (!removeEmptyText_) { removeEmptyText_ = new JSlot(this); focussed().connect(*removeEmptyText_); blurred().connect(*removeEmptyText_); keyWentDown().connect(*removeEmptyText_); std::string jsFunction = "function(obj, event) {" """jQuery.data(" + jsRef() + ", 'obj').applyEmptyText();" "}"; removeEmptyText_->setJavaScript(jsFunction); } } else { delete removeEmptyText_; removeEmptyText_ = 0; } } else { setToolTip(emptyText); } }
void WWidgetVectorPainter::updateContents(std::vector<DomElement *>& result, WPaintDevice *device) { WVectorImage *vectorDevice = dynamic_cast<WVectorImage *>(device); if (widget_->repaintFlags_ & PaintUpdate) { DomElement *painter = DomElement::updateGiven (WT_CLASS ".getElement('p" + widget_->id()+ "').firstChild", DomElement_DIV); painter->setProperty(PropertyAddedInnerHTML, vectorDevice->rendered()); WApplication *app = WApplication::instance(); if (app->environment().agentIsOpera()) painter->callMethod("forceRedraw();"); result.push_back(painter); } else { DomElement *canvas = DomElement::getForUpdate ('p' + widget_->id(), DomElement_DIV); /* * In fact, we should use another property, since we could be using * document.importNode() instead of myImportNode() since the xml does not * need to be interpreted as HTML... */ canvas->setProperty(PropertyInnerHTML, vectorDevice->rendered()); result.push_back(canvas); } widget_->sizeChanged_ = false; delete device; }
void WCssTheme::applyValidationStyle(WWidget *widget, const Wt::WValidator::Result& validation, WFlags<ValidationStyleFlag> styles) const { WApplication *app = WApplication::instance(); LOAD_JAVASCRIPT(app, "js/CssThemeValidate.js", "validate", wtjs1); LOAD_JAVASCRIPT(app, "js/CssThemeValidate.js", "setValidationState", wtjs2); if (app->environment().ajax()) { WStringStream js; js << WT_CLASS ".setValidationState(" << widget->jsRef() << "," << (validation.state() == WValidator::Valid ? 1 : 0) << "," << validation.message().jsStringLiteral() << "," << styles.value() << ");"; widget->doJavaScript(js.str()); } else { bool validStyle = (validation.state() == WValidator::Valid) && (styles & ValidationValidStyle); bool invalidStyle = (validation.state() != WValidator::Valid) && (styles & ValidationInvalidStyle); widget->toggleStyleClass("Wt-valid", validStyle); widget->toggleStyleClass("Wt-invalid", invalidStyle); } }
bool WStackedWidget::loadAnimateJS() { WApplication *app = WApplication::instance(); if (app->environment().supportsCss3Animations()) { LOAD_JAVASCRIPT(app, "js/WStackedWidget.js", "WStackedWidget", wtjs1); return true; } else return false; }
void WDialog::render(WFlags<RenderFlag> flags) { if (flags & RenderFull) { WApplication *app = WApplication::instance(); bool centerX = offset(Left).isAuto() && offset(Right).isAuto(), centerY = offset(Top).isAuto() && offset(Bottom).isAuto(); /* * Make sure layout adjusts to contents preferred width, especially * important for IE workaround which uses static position scheme */ if (app->environment().ajax()) if (width().isAuto()) if (maximumWidth().unit() == WLength::Percentage || maximumWidth().toPixels() == 0) impl_->resolveWidget("layout")->setMaximumSize(999999, maximumHeight()); doJavaScript("new " WT_CLASS ".WDialog(" + app->javaScriptClass() + "," + jsRef() + "," + titleBar_->jsRef() + "," + (centerX ? "1" : "0") + "," + (centerY ? "1" : "0") + ");"); /* * When a dialog is shown immediately for a new session, the recentering * logic comes too late and causes a glitch. Thus we include directly in * the HTML a JavaScript block to mitigate that */ if (!app->environment().agentIsIElt(9)) { std::string js = WString::tr("Wt.WDialog.CenterJS").toUTF8(); Utils::replace(js, "$el", "'" + id() + "'"); Utils::replace(js, "$centerX", centerX ? "1" : "0"); Utils::replace(js, "$centerY", centerY ? "1" : "0"); impl_->bindString ("center-script", "<script>" + js + "</script>", XHTMLUnsafeText); } else impl_->bindEmpty("center-script"); } WCompositeWidget::render(flags); }
std::vector<WCssStyleSheet> WCssTheme::styleSheets() const { std::vector<WCssStyleSheet> result; if (!name_.empty()) { std::string themeDir = resourcesUrl(); WApplication *app = WApplication::instance(); result.push_back(WCssStyleSheet(WLink(themeDir + "wt.css"))); if (app->environment().agentIsIE()) result.push_back(WCssStyleSheet(WLink(themeDir + "wt_ie.css"))); if (app->environment().agent() == WEnvironment::IE6) result.push_back(WCssStyleSheet(WLink(themeDir + "wt_ie6.css"))); } return result; }
void WPushButton::doRedirect() { WApplication *app = WApplication::instance(); if (!app->environment().ajax()) { if (linkState_.link.type() == WLink::InternalPath) app->setInternalPath(linkState_.link.internalPath().toUTF8(), true); else app->redirect(linkState_.link.url()); } }
void AuthModel::setRememberMeCookie(const User& user) { WApplication *app = WApplication::instance(); const AuthService *s = baseAuth(); app->setCookie(s->authTokenCookieName(), s->createAuthToken(user), s->authTokenValidity() * 60, s->authTokenCookieDomain(), "", app->environment().urlScheme() == "https"); }
void MessageBox::setHidden(bool hidden, const WAnimation& animation) { if (hidden != hidden_) { hidden_ = hidden; WApplication *app = WApplication::instance(); if (!hidden) setExposeMask(app); else restoreExposeMask(app); if (hidden) app->doJavaScript(elRef() + ".hide();"); else { std::stringstream config; config << "{a:0"; createConfig(config); config << "}"; std::string var; if (firstDisplay_) { var = elRef() + "=Ext.Msg"; /* fix cursor problem in FF 1.5, 2 */ if (!app->environment().agentIsIE()) app->doJavaScript ("Ext.Msg.getDialog().on('show', function(d) {" "var div = Ext.get(d.el);" "div.setStyle('overflow', 'auto');" "var text = div.select('.ext-mb-textarea', true);" "if (!text.item(0))" "text = div.select('.ext-mb-text', true);" "if (text.item(0))" "text.item(0).dom.select();});"); } else var = elRef(); WApplication::instance() ->doJavaScript(var + ".show(" + config.str() + ");"); if (progress_) { WApplication::instance() ->doJavaScript(elRef() + ".updateProgress(" + boost::lexical_cast<std::string>(progressValue_) + ");"); } firstDisplay_ = false; } } }
void WTimer::gotTimeout() { if (active_) { if (!singleShot_) { *timeout_ = Time() + static_cast<int>(interval_.count()); if (!timerWidget_->jsRepeat()) { WApplication *app = WApplication::instance(); timerWidget_->timerStart(app->environment().ajax()); } } else stop(); } }
WPopupMenuItem *WPopupMenu::exec(const WPoint& p) { if (recursiveEventLoop_) throw WException("WPopupMenu::exec(): already being executed."); WApplication *app = WApplication::instance(); recursiveEventLoop_ = true; popup(p); if (app->environment().isTest()) { app->environment().popupExecuted().emit(this); if (recursiveEventLoop_) throw WException("Test case must close popup menu."); } else { do { app->session()->doRecursiveEventLoop(); } while (recursiveEventLoop_); } return result_; }
/** * @brief Get's the cookie from the app * * @return The cookie that the client's browser is giving us */ const string& BaseSessionHandle::getCookie() const { // First ask the browser WApplication* app = WApplication::instance(); const WEnvironment::CookieMap& cookies = app->environment().cookies(); WEnvironment::CookieMap::const_iterator i = cookies.find(_cookieName); if (i != cookies.end()) { return (*i).second; } // Fall back to cached version // If the browser doesn't have a cookie, we might have just set it and no requests have happened yet // Even if this server side cache is old (and the user has logged out, and the client side cookie deleted) // It shouldn't matter because the session store still won't return a user ID for it. // But still if there is a browser side cookie, that takes precedence return cookieCache; }
WMediaPlayer::WMediaPlayer(MediaType mediaType, WContainerWidget *parent) : WCompositeWidget(parent), mediaType_(mediaType), videoWidth_(0), videoHeight_(0), gui_(this), boundSignals_(0) { for (unsigned i = 0; i < 11; ++i) control_[i] = 0; for (unsigned i = 0; i < 3; ++i) display_[i] = 0; for (unsigned i = 0; i < 2; ++i) progressBar_[i] = 0; WTemplate *impl = new WMediaPlayerImpl(this, tr("Wt.WMediaPlayer.template")); impl->bindString("gui", std::string()); setImplementation(impl); WApplication *app = WApplication::instance(); LOAD_JAVASCRIPT(app, "js/WMediaPlayer.js", "WMediaPlayer", wtjs1); std::string res = WApplication::relativeResourcesUrl() + "jPlayer/"; if (!app->environment().ajax()) app->require(res + "jquery.min.js"); if (app->require(res + "jquery.jplayer.min.js")) app->useStyleSheet(res + "skin/jplayer.blue.monday.css"); if (mediaType_ == Video) setVideoSize(480, 270); #ifndef WT_TARGET_JAVA implementJavaScript(&WMediaPlayer::play, jsPlayerRef() + ".jPlayer('play');"); implementJavaScript(&WMediaPlayer::pause, jsPlayerRef() + ".jPlayer('pause');"); implementJavaScript(&WMediaPlayer::stop, jsPlayerRef() + ".jPlayer('stop');"); #endif }
StdGridLayoutImpl2::~StdGridLayoutImpl2() { WApplication *app = WApplication::instance(); /* * If it is a top-level layout (as opposed to a nested layout), * configure overflow of the container. */ if (parentLayoutImpl() == 0) { if (container() == app->root()) { app->setBodyClass(""); app->setHtmlClass(""); } if (app->environment().agentIsIElt(9) && container()) container()->setOverflow(WContainerWidget::OverflowVisible); } }
void WPushButton::renderHRef(DomElement& element) { if (!linkState_.link.isNull() && !isDisabled()) { WApplication *app = WApplication::instance(); if (!linkState_.clickJS) { linkState_.clickJS = new JSlot(); clicked().connect(*linkState_.clickJS); if (!app->environment().ajax()) clicked().connect(this, &WPushButton::doRedirect); } if (linkState_.link.type() == WLink::InternalPath) linkState_.clickJS->setJavaScript ("function(){" + app->javaScriptClass() + "._p_.setHash(" + jsStringLiteral(linkState_.link.internalPath()) + ",true);" "}"); else { std::string url = linkState_.link.resolveUrl(app); if (linkState_.link.target() == TargetNewWindow) linkState_.clickJS->setJavaScript ("function(){" "window.open(" + jsStringLiteral(url) + ");" "}"); else linkState_.clickJS->setJavaScript ("function(){" "window.location=" + jsStringLiteral(url) + ";" "}"); } clicked().senderRepaint(); // XXX only for Java port necessary } else { delete linkState_.clickJS; linkState_.clickJS = 0; } }
void WTimer::start() { WApplication *app = WApplication::instance(); if (!active_) { if (app && app->timerRoot()) app->timerRoot()->addWidget(std::move(uTimerWidget_)); } active_ = true; *timeout_ = Time() + static_cast<int>(interval_.count()); bool jsRepeat = !singleShot_ && ((app && app->environment().ajax()) || !timeout().isExposedSignal()); timerWidget_->timerStart(jsRepeat); if (!timeoutConnected_) { timeout().connect(this, &WTimer::gotTimeout); timeoutConnected_ = true; } }
CgiEnv::CgiEnv() : m_pimpl(make_unique<CgiEnv::Impl>(this)) { WApplication *app = WApplication::instance(); m_pimpl->ClientInfoIP = app->environment().clientAddress(); m_pimpl->ClientInfoBrowser = app->environment().userAgent(); m_pimpl->ClientInfoReferer = app->environment().referer(); m_pimpl->ExtractClientInfoDetail(); m_pimpl->ClientInfoLocation = (format("%1% %2% %3% %4% %5% %6%") % ClientInfoRecord.city % ClientInfoRecord.region % ClientInfoRecord.country_code % ClientInfoRecord.country_code3 % ClientInfoRecord.country_name % ClientInfoRecord.continent_code).str(); if (ClientInfoRecord.latitude != "" && ClientInfoRecord.longitude != "") { m_pimpl->ClientInfoLocation += (format(" %1%,%2%") % ClientInfoRecord.latitude % ClientInfoRecord.longitude).str(); } algorithm::trim(m_pimpl->ClientInfoLocation); m_pimpl->ServerInfoHost = app->environment().hostName(); m_pimpl->ServerInfoURL = app->environment().urlScheme() + "://" + m_pimpl->ServerInfoHost; m_pimpl->ServerInfoRootLoginUrl = m_pimpl->ServerInfoURL + (algorithm::ends_with(m_pimpl->ServerInfoURL, "/") ? "" : "/") + "?root"; m_pimpl->ServerInfoNoReplyAddr = "no-reply@" + m_pimpl->ServerInfoHost; string queryStr = app->environment().getCgiValue("QUERY_STRING"); m_pimpl->FoundXSS = (queryStr.find("<") != string::npos || queryStr.find(">") != string::npos || queryStr.find("%3C") != string::npos || queryStr.find("%3E") != string::npos || queryStr.find("%3c") != string::npos || queryStr.find("%3e") != string::npos) ? true : false; bool logout = false; SubscriptionData.Subscribe = Subscription::Action::None; Http::ParameterMap map = app->environment().getParameterMap(); for (std::map<string, Http::ParameterValues>::const_iterator it = map.begin(); it != map.end(); ++it) { if (it->first == "lang") { auto itLang = m_pimpl->LanguageMapper.right.find(it->second[0]); if (itLang != m_pimpl->LanguageMapper.right.end()) { m_pimpl->CurrentLanguage = itLang->second; } else { m_pimpl->CurrentLanguage = Language::Invalid; } } if (it->first == "root") { m_pimpl->IsRootLoginRequested = true; } if (it->first == "logout") { logout = true; } if (it->first == "subscribe" && it->second[0] != "") { try { if (it->second[0] == "1" || it->second[0] == "2" || it->second[0] == "-1" || it->second[0] == "-2") { auto action = lexical_cast<short>(it->second[0]); SubscriptionData.Subscribe = static_cast<Subscription::Action>(action); } } catch (...) { SubscriptionData.Subscribe = Subscription::Action::Subscribe; } } if (it->first == "inbox" && it->second[0] != "") { static const regex REGEX(Pool::Storage()->RegexEmail()); smatch result; if (regex_search(it->second[0], result, REGEX)) { SubscriptionData.Inbox.assign(it->second[0]); } } if (it->first == "subscription" && it->second[0] != "") { static const regex REGEX(Pool::Storage()->RegexLanguageArray()); smatch result; if (regex_search(it->second[0], result, REGEX)) { vector<string> vec; split(vec, it->second[0], boost::is_any_of(",")); vector<Subscription::Language> langs; for (const auto &s : vec) { if (s == "en") { langs.push_back(Subscription::Language::En); } else if (s == "fa") { langs.push_back(Subscription::Language::Fa); } } SubscriptionData.Languages = std::move(langs); } } if (it->first == "recipient" && it->second[0] != "") { static const regex REGEX(Pool::Storage()->RegexUuid()); smatch result; if (regex_search(it->second[0], result, REGEX)) { SubscriptionData.Uuid.assign(it->second[0]); } } if (it->first == "token" && it->second[0] != "") { try { string token; Pool::Crypto()->Decrypt(it->second[0], token); SubscriptionData.Timestamp = lexical_cast<time_t>(token); } catch (...) { } } if (it->first == "contact-form") { m_pimpl->IsContactFormRequested = true; } } if (m_pimpl->IsRootLoginRequested && logout) { m_pimpl->IsRootLogoutRequested = true; } }
void WContainerWidget::updateDom(DomElement& element, bool all) { if (all && element.type() == DomElement_LI && isInline()) element.setProperty(PropertyStyleDisplay, "inline"); if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) { AlignmentFlag hAlign = contentAlignment_ & AlignHorizontalMask; bool ltr = WApplication::instance()->layoutDirection() == LeftToRight; switch (hAlign) { case AlignLeft: if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED)) element.setProperty(PropertyStyleTextAlign, ltr ? "left" : "right"); break; case AlignRight: element.setProperty(PropertyStyleTextAlign, ltr ? "right" : "left"); break; case AlignCenter: element.setProperty(PropertyStyleTextAlign, "center"); break; case AlignJustify: #ifndef WT_NO_LAYOUT if (!layout_) #endif // WT_NO_LAYOUT element.setProperty(PropertyStyleTextAlign, "justify"); break; default: break; } if (domElementType() == DomElement_TD) { AlignmentFlag vAlign = contentAlignment_ & AlignVerticalMask; switch (vAlign) { case AlignTop: if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED)) element.setProperty(PropertyStyleVerticalAlign, "top"); break; case AlignMiddle: element.setProperty(PropertyStyleVerticalAlign, "middle"); break; case AlignBottom: element.setProperty(PropertyStyleVerticalAlign, "bottom"); default: break; } } } if (flags_.test(BIT_ADJUST_CHILDREN_ALIGN) || flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) { /* * Welcome to CSS hell. * * Apparently, the text-align property only applies to inline elements. * To center non-inline children, the standard says to set its left and * right margin to 'auto'. * * I assume the same applies for aligning to the right ? */ for (unsigned i = 0; i < children_->size(); ++i) { WWidget *child = (*children_)[i]; if (!child->isInline()) { AlignmentFlag ha = contentAlignment_ & AlignHorizontalMask; if (ha == AlignCenter) { if (!child->margin(Left).isAuto()) child->setMargin(WLength::Auto, Left); if (!child->margin(Right).isAuto()) child->setMargin(WLength::Auto, Right); } else if (ha == AlignRight) { if (!child->margin(Left).isAuto()) child->setMargin(WLength::Auto, Left); } } } flags_.reset(BIT_CONTENT_ALIGNMENT_CHANGED); flags_.reset(BIT_ADJUST_CHILDREN_ALIGN); } if (flags_.test(BIT_PADDINGS_CHANGED) || (all && padding_ && !( padding_[0].isAuto() && padding_[1].isAuto() && padding_[2].isAuto() && padding_[3].isAuto()))) { if ((padding_[0] == padding_[1]) && (padding_[0] == padding_[2]) && (padding_[0] == padding_[3])) element.setProperty(PropertyStylePadding, padding_[0].cssText()); else element.setProperty(PropertyStylePadding, padding_[0].cssText() + " " + padding_[1].cssText() + " " + padding_[2].cssText() + " " + padding_[3].cssText()); flags_.reset(BIT_PADDINGS_CHANGED); } WInteractWidget::updateDom(element, all); if (flags_.test(BIT_OVERFLOW_CHANGED) || (all && overflow_ && !(overflow_[0] == OverflowVisible && overflow_[1] == OverflowVisible))) { static const char *cssText[] = { "visible", "auto", "hidden", "scroll" }; element.setProperty(PropertyStyleOverflowX, cssText[overflow_[0]]); element.setProperty(PropertyStyleOverflowY, cssText[overflow_[1]]); flags_.reset(BIT_OVERFLOW_CHANGED); /* If a container widget has overflow, then, if ever something * inside it has position scheme relative/absolute, it will not * scroll properly unless every element up to the container and including * the container itself has overflow: relative. * * The following fixes the common case: * container (overflow) - container - layout */ WApplication *app = WApplication::instance(); if (app->environment().agentIsIE() && (overflow_[0] == OverflowAuto || overflow_[0] == OverflowScroll)) if (positionScheme() == Static) element.setProperty(PropertyStylePosition, "relative"); } }
void Widget::initExt() { std::string extBaseURL = "ext"; WApplication::readConfigurationProperty("extBaseURL", extBaseURL); if (!extBaseURL.empty() && extBaseURL[extBaseURL.length()-1] != '/') extBaseURL += '/'; WApplication *app = WApplication::instance(); if (app->require(extBaseURL + "ext-base.js", "window['Ext']")) { app->require(extBaseURL + "ext-all.js", "window.Ext['DomHelper']"); app->useStyleSheet(extBaseURL + "resources/css/ext-all.css"); // fixes for Firefox 3: app->styleSheet().addRule(".x-date-middle", "width:130px;"); // rendering glitches on all browsers: app->styleSheet().addRule(".ext-gecko .x-form-text", "margin-top: -1px;"); app->styleSheet().addRule(".ext-safari .x-form-text", "margin-top: -1px;"); app->styleSheet().addRule(".ext-ie .x-form-text", "margin-top: 0px !important;" "margin-bottom: 0px !important;"); app->doJavaScript(/*app->javaScriptClass() + '.' + */ "ExtW = new Array();" "Ext.QuickTips.init();" "Ext.BLANK_IMAGE_URL='" + extBaseURL + "resources/images/default/s.gif';", false); app->declareJavaScriptFunction("deleteExtW", "" "function(id){" "" "var w=ExtW[id];" "" "if(w){" "" "if (w.el && w.destroy) w.destroy();" "" "delete ExtW[id];" "" "}" "" "}"); if (app->environment().agentIsIE()) app->doJavaScript ("if ((typeof Range !== 'undefined')" "" "&& !Range.prototype.createContextualFragment) {" """Range.prototype.createContextualFragment = function(html) {" "" "var startNode = this.startContainer;" "" "var doc = startNode.nodeType == 9 ? startNode :" "" "startNode.ownerDocument;" "" "var container = doc.createElement('div');" "" "container.innerHTML = html;" "" "var frag = doc.createDocumentFragment(), n;" "" "while ( (n = container.firstChild) ) {" "" "frag.appendChild(n);" "" "}" "" "return frag;" """};" "}", false); /* * Normally, Ext does this in its onReady function, but this is not * fired when loading ExtJS on demand. */ std::string bodyClass; if (app->environment().agentIsIE()) { bodyClass = " ext-ie "; bodyClass += app->environment().agent() == WEnvironment::IE6 ? "ext-ie6" : "ext-ie7 "; } else if (app->environment().agentIsSafari()) bodyClass = " ext-safari"; else if (app->environment().agentIsOpera()) bodyClass = " ext-opera"; else if (app->environment().agentIsGecko()) bodyClass = " ext-gecko"; const std::string& ua = app->environment().userAgent(); if (ua.find("Linux") != std::string::npos) bodyClass += " ext-linux"; if (ua.find("Macintosh") != std::string::npos || ua.find("Mac OS X") != std::string::npos) bodyClass += " ext-mac"; app->setBodyClass(app->bodyClass() + bodyClass); app->setHtmlClass(app->htmlClass() + " ext-strict"); } }
void WAbstractToggleButton::updateDom(DomElement& element, bool all) { WApplication *app = WApplication::instance(); const WEnvironment& env = app->environment(); DomElement *input = 0; DomElement *span = 0; DomElement *label = 0; // Already apply theme here because it may determine its organization if (all) app->theme()->apply(this, element, 1); if (element.type() == DomElement_INPUT) input = &element; else { if (all) { input = DomElement::createNew(DomElement_INPUT); input->setName("in" + id()); span = DomElement::createNew(DomElement_SPAN); span->setName("t" + id()); if (element.type() != DomElement_LABEL) { label = DomElement::createNew(DomElement_LABEL); label->setName("l" + id()); } } else { input = DomElement::getForUpdate("in" + id(), DomElement_INPUT); span = DomElement::getForUpdate("t" + id(), DomElement_SPAN); } } if (all) updateInput(*input, all); EventSignal<> *check = voidEventSignal(CHECKED_SIGNAL, false); EventSignal<> *uncheck = voidEventSignal(UNCHECKED_SIGNAL, false); EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false); EventSignal<WMouseEvent> *click = mouseEventSignal(M_CLICK_SIGNAL, false); /* * We piggy-back the checked and uncheck signals on the change signal. * * If agent is IE, then we piggy-back the change on the clicked signal. */ bool piggyBackChangeOnClick = env.agentIsIE(); bool needUpdateChangeSignal = (change && change->needsUpdate(all)) || (check && check->needsUpdate(all)) || (uncheck && uncheck->needsUpdate(all)); bool needUpdateClickedSignal = (click && click->needsUpdate(all)) || (piggyBackChangeOnClick && needUpdateChangeSignal); WFormWidget::updateDom(*input, all); /* * Copy all properties to the exterior element, as they relate to style, * etc... We ignore here attributes (except for tooltip), * see WWebWidget: other attributes need not be moved. * * But -- bug #423, disabled and readonly are properties that should be * kept on the interior element. */ if (&element != input) { if (element.properties().find(PropertyClass) != element.properties().end()) input->addPropertyWord(PropertyClass, element.getProperty(PropertyClass)); element.setProperties(input->properties()); input->clearProperties(); std::string v = element.getProperty(Wt::PropertyDisabled); if (!v.empty()) { input->setProperty(Wt::PropertyDisabled, v); element.removeProperty(Wt::PropertyDisabled); } v = element.getProperty(Wt::PropertyReadOnly); if (!v.empty()) { input->setProperty(Wt::PropertyReadOnly, v); element.removeProperty(Wt::PropertyReadOnly); } v = input->getAttribute("title"); if (!v.empty()) element.setAttribute("title", v); } if (flags_.test(BIT_STATE_CHANGED) || all) { input->setProperty(Wt::PropertyChecked, state_ == Unchecked ? "false" : "true"); if (supportsIndeterminate(env)) input->setProperty(Wt::PropertyIndeterminate, state_ == PartiallyChecked ? "true" : "false"); else input->setProperty(Wt::PropertyStyleOpacity, state_ == PartiallyChecked ? "0.5" : ""); flags_.reset(BIT_STATE_CHANGED); } std::vector<DomElement::EventAction> changeActions; if (needUpdateChangeSignal || (piggyBackChangeOnClick && needUpdateClickedSignal) || all) { std::string dom = "o"; if (check) { if (check->isConnected()) changeActions.push_back (DomElement::EventAction(dom + ".checked", check->javaScript(), check->encodeCmd(), check->isExposedSignal())); check->updateOk(); } if (uncheck) { if (uncheck->isConnected()) changeActions.push_back (DomElement::EventAction("!" + dom + ".checked", uncheck->javaScript(), uncheck->encodeCmd(), uncheck->isExposedSignal())); uncheck->updateOk(); } if (change) { if (change->isConnected()) changeActions.push_back (DomElement::EventAction(std::string(), change->javaScript(), change->encodeCmd(), change->isExposedSignal())); change->updateOk(); } if (!piggyBackChangeOnClick) { if (!(all && changeActions.empty())) input->setEvent("change", changeActions); } } if (needUpdateClickedSignal || all) { if (piggyBackChangeOnClick) { if (click) { changeActions.push_back (DomElement::EventAction(std::string(), click->javaScript(), click->encodeCmd(), click->isExposedSignal())); click->updateOk(); } if (!(all && changeActions.empty())) input->setEvent(CLICK_SIGNAL, changeActions); } else if (click) updateSignalConnection(*input, *click, CLICK_SIGNAL, all); } if (span) { if (all || flags_.test(BIT_TEXT_CHANGED)) { span->setProperty(PropertyInnerHTML, text_.formattedText()); if(all || flags_.test(BIT_WORD_WRAP_CHANGED)) { span->setProperty(PropertyStyleWhiteSpace, flags_.test(BIT_WORD_WRAP) ? "normal" : "nowrap"); flags_.reset(BIT_WORD_WRAP_CHANGED); } flags_.reset(BIT_TEXT_CHANGED); } } if (&element != input) { if (label) { label->addChild(input); label->addChild(span); element.addChild(label); } else { element.addChild(input); element.addChild(span); } } }
void WAbstractToggleButton::updateDom(DomElement& element, bool all) { WApplication *app = WApplication::instance(); const WEnvironment& env = app->environment(); DomElement *input = 0; DomElement *span = 0; if (element.type() == DomElement_LABEL) { if (all) { input = DomElement::createNew(DomElement_INPUT); input->setName("in" + id()); span = DomElement::createNew(DomElement_SPAN); span->setName("l" + id()); } else { input = DomElement::getForUpdate("in" + id(), DomElement_INPUT); span = DomElement::getForUpdate("l" + id(), DomElement_SPAN); } } else input = &element; if (all) updateInput(*input, all); EventSignal<> *check = voidEventSignal(CHECKED_SIGNAL, false); EventSignal<> *uncheck = voidEventSignal(UNCHECKED_SIGNAL, false); EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false); EventSignal<WMouseEvent> *click = mouseEventSignal(M_CLICK_SIGNAL, false); /* * We piggy-back the checked and uncheck signals on the change signal. * * If agent is IE, then we piggy-back the change on the clicked signal. */ bool piggyBackChangeOnClick = env.agentIsIE(); bool needUpdateChangeSignal = (change && change->needsUpdate(all)) || (check && check->needsUpdate(all)) || (uncheck && uncheck->needsUpdate(all)); bool needUpdateClickedSignal = (click && click->needsUpdate(all)) || (piggyBackChangeOnClick && needUpdateChangeSignal); WFormWidget::updateDom(*input, all); /* * Copy all properties to the exterior element, as they relate to style, * etc... We ignore here attributes, see WWebWidget: there seems not to * be attributes that sensibly need to be moved. * * But -- bug #423, disabled and readonly are properties that should be * kept on the interior element. */ if (&element != input) { element.setProperties(input->properties()); input->clearProperties(); std::string v = element.getProperty(Wt::PropertyDisabled); if (!v.empty()) { input->setProperty(Wt::PropertyDisabled, v); element.removeProperty(Wt::PropertyDisabled); } v = element.getProperty(Wt::PropertyReadOnly); if (!v.empty()) { input->setProperty(Wt::PropertyReadOnly, v); element.removeProperty(Wt::PropertyReadOnly); } } if (stateChanged_ || all) { input->setProperty(Wt::PropertyChecked, state_ == Unchecked ? "false" : "true"); if (supportsIndeterminate(env)) input->setProperty(Wt::PropertyIndeterminate, state_ == PartiallyChecked ? "true" : "false"); else input->setProperty(Wt::PropertyStyleOpacity, state_ == PartiallyChecked ? "0.5" : ""); stateChanged_ = false; } std::vector<DomElement::EventAction> changeActions; if (needUpdateChangeSignal || (piggyBackChangeOnClick && needUpdateClickedSignal) || all) { std::string dom = "o"; if (check) { if (check->isConnected()) changeActions.push_back (DomElement::EventAction(dom + ".checked", check->javaScript(), check->encodeCmd(), check->isExposedSignal())); check->updateOk(); } if (uncheck) { if (uncheck->isConnected()) changeActions.push_back (DomElement::EventAction("!" + dom + ".checked", uncheck->javaScript(), uncheck->encodeCmd(), uncheck->isExposedSignal())); uncheck->updateOk(); } if (change) { if (change->needsUpdate(all)) changeActions.push_back (DomElement::EventAction(std::string(), change->javaScript(), change->encodeCmd(), change->isExposedSignal())); change->updateOk(); } if (!piggyBackChangeOnClick) { if (!(all && changeActions.empty())) input->setEvent("change", changeActions); } } if (needUpdateClickedSignal || all) { if (piggyBackChangeOnClick) { if (click) { changeActions.push_back (DomElement::EventAction(std::string(), click->javaScript(), click->encodeCmd(), click->isExposedSignal())); click->updateOk(); } if (!(all && changeActions.empty())) input->setEvent(CLICK_SIGNAL, changeActions); } else if (click) updateSignalConnection(*input, *click, CLICK_SIGNAL, all); } if (span) { if (all || textChanged_) { span->setProperty(PropertyInnerHTML, text_.formattedText()); textChanged_ = false; } } if (&element != input) { element.addChild(input); element.addChild(span); } }
void WInteractWidget::updateDom(DomElement& element, bool all) { bool updateKeyDown = false; WApplication *app = WApplication::instance(); /* * -- combine enterPress, escapePress and keyDown signals */ EventSignal<> *enterPress = voidEventSignal(ENTER_PRESS_SIGNAL, false); EventSignal<> *escapePress = voidEventSignal(ESCAPE_PRESS_SIGNAL, false); EventSignal<WKeyEvent> *keyDown = keyEventSignal(KEYDOWN_SIGNAL, false); updateKeyDown = (enterPress && enterPress->needsUpdate(all)) || (escapePress && escapePress->needsUpdate(all)) || (keyDown && keyDown->needsUpdate(all)); if (updateKeyDown) { std::vector<DomElement::EventAction> actions; if (enterPress) { if (enterPress->needsUpdate(true)) { /* * prevent enterPressed from triggering a changed event on all * browsers except for Opera and IE */ std::string extraJS; const WEnvironment& env = app->environment(); if (dynamic_cast<WFormWidget *>(this) && !env.agentIsOpera() && !env.agentIsIE()) extraJS = "var g=this.onchange;" "" "this.onchange=function(){this.onchange=g;};"; actions.push_back (DomElement::EventAction("e.keyCode && (e.keyCode == 13)", enterPress->javaScript() + extraJS, enterPress->encodeCmd(), enterPress->isExposedSignal())); } enterPress->updateOk(); } if (escapePress) { if (escapePress->needsUpdate(true)) { actions.push_back (DomElement::EventAction("e.keyCode && (e.keyCode == 27)", escapePress->javaScript(), escapePress->encodeCmd(), escapePress->isExposedSignal())); } escapePress->updateOk(); } if (keyDown) { if (keyDown->needsUpdate(true)) { actions.push_back (DomElement::EventAction(std::string(), keyDown->javaScript(), keyDown->encodeCmd(), keyDown->isExposedSignal())); } keyDown->updateOk(); } if (!actions.empty()) element.setEvent("keydown", actions); else if (!all) element.setEvent("keydown", std::string(), std::string()); } /* * -- allow computation of dragged mouse distance */ EventSignal<WMouseEvent> *mouseDown = mouseEventSignal(MOUSE_DOWN_SIGNAL, false); EventSignal<WMouseEvent> *mouseUp = mouseEventSignal(MOUSE_UP_SIGNAL, false); EventSignal<WMouseEvent> *mouseMove = mouseEventSignal(MOUSE_MOVE_SIGNAL, false); EventSignal<WMouseEvent> *mouseDrag = mouseEventSignal(MOUSE_DRAG_SIGNAL, false); bool updateMouseMove = (mouseMove && mouseMove->needsUpdate(all)) || (mouseDrag && mouseDrag->needsUpdate(all)); bool updateMouseDown = (mouseDown && mouseDown->needsUpdate(all)) || updateMouseMove; bool updateMouseUp = (mouseUp && mouseUp->needsUpdate(all)) || updateMouseMove; std::string CheckDisabled = "if($(o).hasClass('" + app->theme()->disabledClass() + "')){" WT_CLASS ".cancelEvent(e);return;}"; if (updateMouseDown) { /* * when we have a mouseUp event, we also need a mouseDown event * to be able to compute dragDX/Y. * * When we have: * - a mouseDrag * - or a mouseDown + (mouseMove or mouseUp), * we need to capture everything after on mouse down, and keep track of the * down button if we have a mouseMove or mouseDrag */ WStringStream js; js << CheckDisabled; if (mouseUp && mouseUp->isConnected()) js << app->javaScriptClass() << "._p_.saveDownPos(event);"; if ((mouseDrag && mouseDrag->isConnected()) || (mouseDown && mouseDown->isConnected() && ((mouseUp && mouseUp->isConnected()) || (mouseMove && mouseMove->isConnected())))) js << WT_CLASS ".capture(this);"; if ((mouseMove && mouseMove->isConnected()) || (mouseDrag && mouseDrag->isConnected())) js << WT_CLASS ".mouseDown(e);"; if (mouseDown) { js << mouseDown->javaScript(); element.setEvent("mousedown", js.str(), mouseDown->encodeCmd(), mouseDown->isExposedSignal()); mouseDown->updateOk(); } else element.setEvent("mousedown", js.str(), std::string(), false); } if (updateMouseUp) { WStringStream js; /* * when we have a mouseMove or mouseDrag event, we need to keep track * of unpressing the button. */ js << CheckDisabled; if ((mouseMove && mouseMove->isConnected()) || (mouseDrag && mouseDrag->isConnected())) js << WT_CLASS ".mouseUp(e);"; if (mouseUp) { js << mouseUp->javaScript(); element.setEvent("mouseup", js.str(), mouseUp->encodeCmd(), mouseUp->isExposedSignal()); mouseUp->updateOk(); } else element.setEvent("mouseup", js.str(), std::string(), false); } if (updateMouseMove) { /* * We need to mix mouseDrag and mouseMove events. */ std::vector<DomElement::EventAction> actions; if (mouseMove) { actions.push_back (DomElement::EventAction(std::string(), mouseMove->javaScript(), mouseMove->encodeCmd(), mouseMove->isExposedSignal())); mouseMove->updateOk(); } if (mouseDrag) { actions.push_back (DomElement::EventAction(WT_CLASS ".buttons", mouseDrag->javaScript() + WT_CLASS ".drag(e);", mouseDrag->encodeCmd(), mouseDrag->isExposedSignal())); mouseDrag->updateOk(); } element.setEvent("mousemove", actions); } /* * -- mix mouseClick and mouseDblClick events in mouseclick since we * only want to fire one of both */ EventSignal<WMouseEvent> *mouseClick = mouseEventSignal(M_CLICK_SIGNAL, false); EventSignal<WMouseEvent> *mouseDblClick = mouseEventSignal(DBL_CLICK_SIGNAL, false); bool updateMouseClick = (mouseClick && mouseClick->needsUpdate(all)) || (mouseDblClick && mouseDblClick->needsUpdate(all)); if (updateMouseClick) { WStringStream js; js << CheckDisabled; if (mouseDrag) js << "if (" WT_CLASS ".dragged()) return;"; if (mouseDblClick && mouseDblClick->needsUpdate(all)) { /* * Click: if timer is running: * - clear timer, dblClick() * - start timer, clear timer and click() */ /* We have to prevent this immediately ! */ if (mouseClick) { if (mouseClick->defaultActionPrevented() || mouseClick->propagationPrevented()) { js << WT_CLASS ".cancelEvent(e"; if (mouseClick->defaultActionPrevented() && mouseClick->propagationPrevented()) js << ");"; else if (mouseClick->defaultActionPrevented()) js << ",0x2);"; else js << ",0x1);"; } } js << "if(" WT_CLASS ".isDblClick(o, e)) {" << mouseDblClick->javaScript(); if (mouseDblClick->isExposedSignal()) js << app->javaScriptClass() << "._p_.update(o,'" << mouseDblClick->encodeCmd() << "',e,true);"; mouseDblClick->updateOk(); js << "}else{" """if (" WT_CLASS ".isIElt9 && document.createEventObject) " "" "e = document.createEventObject(e);" """o.wtE1 = e;" """o.wtClickTimeout = setTimeout(function() {" "" "o.wtClickTimeout = null; o.wtE1 = null;"; if (mouseClick) { js << mouseClick->javaScript(); if (mouseClick->isExposedSignal()) { js << app->javaScriptClass() << "._p_.update(o,'" << mouseClick->encodeCmd() << "',e,true);"; } mouseClick->updateOk(); } const Configuration& conf = app->environment().server()->configuration(); js << "}," << conf.doubleClickTimeout() << ");}"; } else { if (mouseClick && mouseClick->needsUpdate(all)) { js << mouseClick->javaScript(); if (mouseClick->isExposedSignal()) { js << app->javaScriptClass() << "._p_.update(o,'" << mouseClick->encodeCmd() << "',e,true);"; } mouseClick->updateOk(); } } element.setEvent(CLICK_SIGNAL, js.str(), mouseClick ? mouseClick->encodeCmd() : ""); if (mouseDblClick) { if (app->environment().agentIsIElt(9)) element.setEvent("dblclick", "this.onclick()"); } } /* * -- mouseOver with delay */ EventSignal<WMouseEvent> *mouseOver = mouseEventSignal(MOUSE_OVER_SIGNAL, false); EventSignal<WMouseEvent> *mouseOut = mouseEventSignal(MOUSE_OUT_SIGNAL, false); bool updateMouseOver = mouseOver && mouseOver->needsUpdate(all); if (mouseOverDelay_) { if (updateMouseOver) { WStringStream js; js << "o.over=setTimeout(function() {" << "o.over = null;" << mouseOver->javaScript(); if (mouseOver->isExposedSignal()) { js << app->javaScriptClass() << "._p_.update(o,'" << mouseOver->encodeCmd() << "',e,true);"; } js << "}," << mouseOverDelay_ << ");"; element.setEvent("mouseover", js.str(), ""); mouseOver->updateOk(); if (!mouseOut) mouseOut = mouseEventSignal(MOUSE_OUT_SIGNAL, true); element.setEvent("mouseout", "clearTimeout(o.over); o.over=null;" + mouseOut->javaScript(), mouseOut->encodeCmd(), mouseOut->isExposedSignal()); mouseOut->updateOk(); } } else { if (updateMouseOver) { element.setEventSignal("mouseover", *mouseOver); mouseOver->updateOk(); } bool updateMouseOut = mouseOut && mouseOut->needsUpdate(all); if (updateMouseOut) { element.setEventSignal("mouseout", *mouseOut); mouseOut->updateOk(); } } updateEventSignals(element, all); WWebWidget::updateDom(element, all); }
void WAnchor::updateDom(DomElement& element, bool all) { if (element.type() != DomElement_A) { WContainerWidget::updateDom(element, all); return; } if (flags_.test(BIT_CHANGE_TAG)) { if (!all) element.callJavaScript(WT_CLASS ".changeTag(" + jsRef() + ",'a');"); flags_.reset(BIT_CHANGE_TAG); } bool needsUrlResolution = false; if (flags_.test(BIT_LINK_CHANGED) || all) { WApplication *app = WApplication::instance(); std::string url = link_.resolveUrl(app); /* * From 但浩亮: setRefInternalPath() and setTarget(TargetNewWindow) * does not work without the check below: */ if (target_ == TargetSelf) changeInternalPathJS_ = link_.manageInternalPathChange(app, this, changeInternalPathJS_); else { delete changeInternalPathJS_; changeInternalPathJS_ = 0; } url = app->encodeUntrustedUrl(url); std::string href = resolveRelativeUrl(url); element.setAttribute("href", href); needsUrlResolution = !app->environment().hashInternalPaths() && href.find("://") == std::string::npos && href[0] != '/'; flags_.reset(BIT_LINK_CHANGED); } if (flags_.test(BIT_TARGET_CHANGED) || all) { switch (target_) { case TargetSelf: if (!all) element.setProperty(PropertyTarget, "_self"); break; case TargetThisWindow: element.setProperty(PropertyTarget, "_top"); break; case TargetNewWindow: element.setProperty(PropertyTarget, "_blank"); } flags_.reset(BIT_TARGET_CHANGED); } WContainerWidget::updateDom(element, all); if (needsUrlResolution) { if (all) element.setProperty(PropertyClass, Utils::addWord(styleClass().toUTF8(), "Wt-rr")); else element.callJavaScript("$('#" + id() + "').addClass('Wt-rr');"); } }
void WDialog::create() { closeIcon_ = 0; footer_ = 0; modal_ = true; resizable_ = false; recursiveEventLoop_ = false; impl_ = dynamic_cast<WTemplate *>(implementation()); const char *CSS_RULES_NAME = "Wt::WDialog"; WApplication *app = WApplication::instance(); if (!app->styleSheet().isDefined(CSS_RULES_NAME)) { /* Needed for the dialog cover */ if (app->environment().agentIsIElt(9)) app->styleSheet().addRule("body", "height: 100%;"); std::string position = app->environment().agent() == WEnvironment::IE6 ? "absolute" : "fixed"; // we use left: 50%, top: 50%, margin hack when JavaScript is not available // see below for an IE workaround app->styleSheet().addRule("div.Wt-dialog", std::string() + (app->environment().ajax() ? "visibility: hidden;" : "") //"position: " + position + ';' + (!app->environment().ajax() ? "left: 50%; top: 50%;" "margin-left: -100px; margin-top: -50px;" : "left: 0px; top: 0px;"), CSS_RULES_NAME); if (app->environment().agent() == WEnvironment::IE6) { app->styleSheet().addRule ("div.Wt-dialogcover", "position: absolute;" "left: expression(" "(ignoreMe2 = document.documentElement.scrollLeft) + 'px' );" "top: expression(" "(ignoreMe = document.documentElement.scrollTop) + 'px' );"); // simulate position: fixed left: 50%; top 50% if (!app->environment().ajax()) app->styleSheet().addRule ("div.Wt-dialog", "position: absolute;" "left: expression(" "(ignoreMe2 = document.documentElement.scrollLeft + " "document.documentElement.clientWidth/2) + 'px' );" "top: expression(" "(ignoreMe = document.documentElement.scrollTop + " "document.documentElement.clientHeight/2) + 'px' );"); } } LOAD_JAVASCRIPT(app, "js/WDialog.js", "WDialog", wtjs1); WContainerWidget *layoutContainer = new WContainerWidget(); layoutContainer->setStyleClass("dialog-layout"); WVBoxLayout *layout = new WVBoxLayout(layoutContainer); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); impl_->bindWidget("layout", layoutContainer); titleBar_ = new WContainerWidget(); app->theme()->apply(this, titleBar_, DialogTitleBarRole); caption_ = new WText(titleBar_); caption_->setInline(false); contents_ = new WContainerWidget(); app->theme()->apply(this, contents_, DialogBodyRole); layout->addWidget(titleBar_); layout->addWidget(contents_, 1); saveCoverState(app, app->dialogCover()); /* * Cannot be done using the CSS stylesheet in case there are * contained elements with setHideWithOffsets() set * * For IE, we cannot set it yet since it will confuse width measurements * to become minimum size instead of (unconstrained) preferred size */ if (app->environment().ajax()) { setAttributeValue("style", "visibility: hidden"); /* * This is needed for animations only, but setting absolute or * fixed positioning confuses layout measurement in IE browsers */ if (!app->environment().agentIsIElt(9)) setPositionScheme(Fixed); } else setPositionScheme(app->environment().agent() == WEnvironment::IE6 ? Absolute : Fixed); }
void WPushButton::updateDom(DomElement& element, bool all) { if (all) { element.setAttribute("type", "button"); element.setProperty(PropertyClass, "Wt-btn"); } if (flags_.test(BIT_ICON_CHANGED) || (all && !icon_.isNull())) { DomElement *image = DomElement::createNew(DomElement_IMG); image->setProperty(PropertySrc, icon_.url()); image->setId("im" + formName()); element.insertChildAt(image, 0); flags_.set(BIT_ICON_RENDERED); } if (flags_.test(BIT_TEXT_CHANGED) || all) { element .setProperty(Wt::PropertyInnerHTML, text_.literal() ? escapeText(text_, true).toUTF8() : text_.toUTF8()); flags_.reset(BIT_TEXT_CHANGED); } if (flags_.test(BIT_LINK_CHANGED) || (all && !link_.isNull())) { if (!link_.isNull()) { WApplication *app = WApplication::instance(); if (!redirectJS_) { redirectJS_ = new JSlot(); clicked().connect(*redirectJS_); if (!app->environment().ajax()) clicked().connect(this, &WPushButton::doRedirect); } if (link_.type() == WLink::InternalPath) redirectJS_->setJavaScript ("function(){" WT_CLASS ".history.navigate(" + jsStringLiteral(link_.internalPath()) + ",true);" "}"); else if (linkTarget_ == TargetNewWindow) redirectJS_->setJavaScript ("function(){" "window.open(" + jsStringLiteral(link_.url()) + ");" "}"); else redirectJS_->setJavaScript ("function(){" "window.location=" + jsStringLiteral(link_.url()) + ";" "}"); clicked().senderRepaint(); // XXX only for Java port necessary } else { delete redirectJS_; redirectJS_ = 0; } } WFormWidget::updateDom(element, all); }