diff --git a/WebWidgets/ExtJS/include/Poco/WebWidgets/ExtJS/Utility.h b/WebWidgets/ExtJS/include/Poco/WebWidgets/ExtJS/Utility.h index e8cd0506f..b780f3bd9 100644 --- a/WebWidgets/ExtJS/include/Poco/WebWidgets/ExtJS/Utility.h +++ b/WebWidgets/ExtJS/include/Poco/WebWidgets/ExtJS/Utility.h @@ -104,14 +104,31 @@ public: static std::string convertPocoDateToPHPDate(const std::string& dateTimeFmt); /// Converts a poco date time format string to its PHP/extjs equivalent - - static bool writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates); + + template + static bool writeJSEvent(std::ostream& out, const std::string& eventName, const JavaScriptEvent& ev, CreateServerCallbackFct fct, const Param* p) + { + if (!ev.hasJavaScriptCode()) + return false; + if (ev.willDoServerCallback()) + return writeJSEvent(out, eventName, ev.jsDelegates(), (*fct)(p), ev.getServerCallbackPos(), ev.getDelayTime(), ev.getGroupEvents()); + return writeJSEvent(out, eventName, ev.jsDelegates(), ev.getDelayTime(), ev.getGroupEvents()); + } + + + static bool writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates, int delayTime, bool group); /// writes all JS Delegates for a single named JSEvent. /// Returns true if data was written, false if no delegates were present and no event handler was written. - static bool writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates, const Poco::WebWidgets::JSDelegate& serverCallback, std::size_t serverCallPos); + static bool writeJSEvent(std::ostream& out, + const std::string& eventName, + const std::list& delegates, + const Poco::WebWidgets::JSDelegate& serverCallback, + std::size_t serverCallPos, + int delayTime, + bool group); /// writes all JS Delegates for a single named JSEvent. plus the server callbacb, Always returns true. - + static std::string createURI(const std::map& addParams, Renderable::ID id); /// Creates the url from the function parameters, adds the id parameter automatically /// a WebApplication must be set! diff --git a/WebWidgets/ExtJS/src/ButtonCellRenderer.cpp b/WebWidgets/ExtJS/src/ButtonCellRenderer.cpp index e824f0d30..f1e1d72ad 100644 --- a/WebWidgets/ExtJS/src/ButtonCellRenderer.cpp +++ b/WebWidgets/ExtJS/src/ButtonCellRenderer.cpp @@ -113,11 +113,13 @@ void ButtonCellRenderer::renderProperties(const ButtonCell* pButtonCell, const s if (pOwner->buttonClicked.hasJavaScriptCode()) { ostr << ",listeners:{"; + Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked, &ButtonCellRenderer::createClickServerCallback, pOwner); + /* if (pOwner->buttonClicked.willDoServerCallback()) Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates(), createClickServerCallback(pOwner), pOwner->buttonClicked.getServerCallbackPos()); else - Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates()); + Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates());*/ ostr << "}"; } } diff --git a/WebWidgets/ExtJS/src/ComboBoxCellRenderer.cpp b/WebWidgets/ExtJS/src/ComboBoxCellRenderer.cpp index d8d902418..185573d49 100644 --- a/WebWidgets/ExtJS/src/ComboBoxCellRenderer.cpp +++ b/WebWidgets/ExtJS/src/ComboBoxCellRenderer.cpp @@ -103,10 +103,7 @@ void ComboBoxCellRenderer::renderHead(const Renderable* pRenderable, const Rende if (pComboOwner && pComboOwner->selected.hasJavaScriptCode()) { ostr << ",listeners:{"; - if (pComboOwner->selected.willDoServerCallback()) - Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected.jsDelegates(), createSelectedServerCallback(pComboOwner), pComboOwner->selected.getServerCallbackPos()); - else - Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected.jsDelegates()); + Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected, &ComboBoxCellRenderer::createSelectedServerCallback, pComboOwner); if (!tooltip.empty()) ostr << ",render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}"; ostr << "}"; diff --git a/WebWidgets/ExtJS/src/PageRenderer.cpp b/WebWidgets/ExtJS/src/PageRenderer.cpp index 07cc981f5..96006e8f0 100644 --- a/WebWidgets/ExtJS/src/PageRenderer.cpp +++ b/WebWidgets/ExtJS/src/PageRenderer.cpp @@ -145,17 +145,13 @@ void PageRenderer::renderHead(const Renderable* pRenderable, const RenderContext if (pPage->beforeRender.hasJavaScriptCode() || pPage->afterRender.hasJavaScriptCode()) { ostr << ",listeners:{"; - bool written = false; - if (pPage->beforeRender.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender.jsDelegates(), createBeforeRenderCallback(pPage), pPage->beforeRender.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender.jsDelegates()); - if (written) - ostr << ","; - if (pPage->afterRender.willDoServerCallback()) - Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender.jsDelegates(), createAfterRenderCallback(pPage), pPage->afterRender.getServerCallbackPos()); - else - Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender.jsDelegates()); + bool written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender, &PageRenderer::createBeforeRenderCallback, pPage); + if (pPage->afterRender.hasJavaScriptCode()) + { + if (written) + ostr << ","; + Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender, &PageRenderer::createAfterRenderCallback, pPage); + } ostr << "}"; } if (pPage->getHeight() > 0) diff --git a/WebWidgets/ExtJS/src/TableRenderer.cpp b/WebWidgets/ExtJS/src/TableRenderer.cpp index 7477fb910..972b8927c 100644 --- a/WebWidgets/ExtJS/src/TableRenderer.cpp +++ b/WebWidgets/ExtJS/src/TableRenderer.cpp @@ -303,100 +303,62 @@ void TableRenderer::renderProperties(const Table* pTable, const RenderContext& c if (pTable->cellValueChanged.willDoServerCallback()) written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, modList, TableRenderer::createCellValueChangedServerCallback(pTable), - pTable->cellValueChanged.getServerCallbackPos()); + pTable->cellValueChanged.getServerCallbackPos(), pTable->cellValueChanged.getDelayTime(), pTable->cellValueChanged.getGroupEvents()); else - written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, modList); + written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, modList, pTable->cellValueChanged.getDelayTime(), pTable->cellValueChanged.getGroupEvents()); if (pTable->beforeCellValueChanged.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->beforeCellValueChanged.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_BEFORECELLVALUECHANGED, pTable->beforeCellValueChanged.jsDelegates(), - TableRenderer::createBeforeCellValueChangedServerCallback(pTable), - pTable->beforeCellValueChanged.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_BEFORECELLVALUECHANGED, pTable->beforeCellValueChanged.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_BEFORECELLVALUECHANGED, pTable->beforeCellValueChanged, + &TableRenderer::createBeforeCellValueChangedServerCallback, pTable); } if (pTable->keyDown.hasJavaScriptCode()) { if (written) ostr << ","; - if (pTable->keyDown.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_KEYDOWN, pTable->keyDown.jsDelegates(), - TableRenderer::createKeyDownServerCallback(pTable), - pTable->keyDown.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_KEYDOWN, pTable->keyDown.jsDelegates()); + written = Utility::writeJSEvent(ostr, EV_KEYDOWN, pTable->keyDown, + &TableRenderer::createKeyDownServerCallback, pTable); } if (pTable->keyPressed.hasJavaScriptCode()) { if (written) ostr << ","; - if (pTable->keyPressed.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_KEYPRESSED, pTable->keyPressed.jsDelegates(), - TableRenderer::createKeyPressedServerCallback(pTable), - pTable->keyPressed.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_KEYPRESSED, pTable->keyPressed.jsDelegates()); + written = Utility::writeJSEvent(ostr, EV_KEYPRESSED, pTable->keyPressed, + &TableRenderer::createKeyPressedServerCallback, pTable); } } if (pTable->cellClicked.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->cellClicked.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked.jsDelegates(), - TableRenderer::createCellClickedServerCallback(pTable), - pTable->cellClicked.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked, + &TableRenderer::createCellClickedServerCallback, pTable); } if (pTable->beforeCellClicked.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->beforeCellClicked.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_BEFORECELLCLICKED, pTable->beforeCellClicked.jsDelegates(), - TableRenderer::createBeforeCellClickedServerCallback(pTable), - pTable->beforeCellClicked.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_BEFORECELLCLICKED, pTable->beforeCellClicked.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_BEFORECELLCLICKED, pTable->beforeCellClicked, + &TableRenderer::createBeforeCellClickedServerCallback ,pTable); } if (pTable->afterRender.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->afterRender.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_RENDER, pTable->afterRender.jsDelegates(), - TableRenderer::createRenderServerCallback(pTable), - pTable->afterRender.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_RENDER, pTable->afterRender.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_RENDER, pTable->afterRender, + &TableRenderer::createRenderServerCallback, pTable); } if (pTable->mouseUp.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->mouseUp.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_MOUSEUP, pTable->mouseUp.jsDelegates(), - TableRenderer::createMouseUpServerCallback(pTable), - pTable->mouseUp.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_MOUSEUP, pTable->mouseUp.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_MOUSEUP, pTable->mouseUp, + &TableRenderer::createMouseUpServerCallback, pTable); } if (pTable->mouseDown.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->mouseDown.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_MOUSEDOWN, pTable->mouseDown.jsDelegates(), - TableRenderer::createMouseDownServerCallback(pTable), - pTable->mouseDown.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_MOUSEDOWN, pTable->mouseDown.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_MOUSEDOWN, pTable->mouseDown, + &TableRenderer::createMouseDownServerCallback, pTable); } ostr << "},"; //close listeners @@ -417,23 +379,14 @@ void TableRenderer::renderProperties(const Table* pTable, const RenderContext& c if (pTable->rowClicked.hasJavaScriptCode() || pTable->beforeRowClicked.hasJavaScriptCode()) { ostr << ",listeners:{"; - if (pTable->rowClicked.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked.jsDelegates(), - TableRenderer::createRowClickedServerCallback(pTable), - pTable->rowClicked.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked.jsDelegates()); + written = Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked, + &TableRenderer::createRowClickedServerCallback, pTable); if (pTable->beforeRowClicked.hasJavaScriptCode()) { - if (written) - ostr << ","; - if (pTable->beforeRowClicked.willDoServerCallback()) - written = Utility::writeJSEvent(ostr, EV_BEFOREROWCLICKED, pTable->beforeRowClicked.jsDelegates(), - TableRenderer::createBeforeRowClickedServerCallback(pTable), - pTable->beforeRowClicked.getServerCallbackPos()); - else - written = Utility::writeJSEvent(ostr, EV_BEFOREROWCLICKED, pTable->beforeRowClicked.jsDelegates()); + if (written) ostr << ","; + written = Utility::writeJSEvent(ostr, EV_BEFOREROWCLICKED, pTable->beforeRowClicked, + &TableRenderer::createBeforeRowClickedServerCallback, pTable); } ostr << "}"; } @@ -610,10 +563,7 @@ void TableRenderer::renderStore(const Table* pTable, std::ostream& ostr) if (pTable->afterLoad.hasJavaScriptCode()) { ostr << ",listeners:{"; - if (pTable->afterLoad.willDoServerCallback()) - Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad.jsDelegates(), createAfterLoadServerCallback(pTable), pTable->afterLoad.getServerCallbackPos()); - else - Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad.jsDelegates()); + Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad, &TableRenderer::createAfterLoadServerCallback, pTable); ostr << "}"; } diff --git a/WebWidgets/ExtJS/src/Utility.cpp b/WebWidgets/ExtJS/src/Utility.cpp index c2bc83afe..40722c385 100644 --- a/WebWidgets/ExtJS/src/Utility.cpp +++ b/WebWidgets/ExtJS/src/Utility.cpp @@ -414,7 +414,7 @@ Form::Ptr Utility::insideForm(const Cell* pChild) } -bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates) +bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates, int delayTime, bool group) { //'click' : { // fn: this.onClick, @@ -424,17 +424,17 @@ bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, cons if (delegates.empty()) return false; - out << "'" << eventName << "':"; + out << "'" << eventName << "':{"; if (delegates.size() == 1) - out << "{fn:" << delegates.begin()->jsCode() << "}"; + out << "fn:" << delegates.begin()->jsCode() << ""; else { // rather simple way to support more than one delegate std::ostringstream invoke; int maxParams = detectMaxParamCount(delegates); std::string fct(createFunctionSignature(maxParams)); - out << "{fn:" << fct << "{var all={"; + out << "fn:" << fct << "{var all={"; // the invoke function calls all the other functions sequentially invoke << "invoke:" << fct <<"{"; std::list::const_iterator it = delegates.begin(); @@ -480,20 +480,33 @@ bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, cons out << "all." << createFunctionSignature("invoke", maxParams) << ";"; out << "}"; //closes fn - out << "}"; //closes function + } - + if (delayTime > 0) + { + if (!group) + out << ",delay:" << delayTime; + else + out << ",buffer:" << delayTime; + } + out << "}"; //closes outer fn return true; } -bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, const std::list& delegates, const Poco::WebWidgets::JSDelegate& serverCallback, std::size_t serverCallPos) +bool Utility::writeJSEvent(std::ostream& out, + const std::string& eventName, + const std::list& delegates, + const Poco::WebWidgets::JSDelegate& serverCallback, + std::size_t serverCallPos, + int delayTime, + bool group) { // TODO: we can optimize here a bit by avoiding the copy std::list dels; std::list::const_iterator it = delegates.begin(); bool written = false; - for (; it != delegates.end(); ++it, --serverCallPos) + for (; it != delegates.end() && !written; ++it, --serverCallPos) { if (serverCallPos == 0) { @@ -504,7 +517,7 @@ bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, cons } if (!written) dels.push_back(serverCallback); - return writeJSEvent(out, eventName, dels); + return writeJSEvent(out, eventName, dels, delayTime, group); } diff --git a/WebWidgets/ExtJS/testsuite/src/ExtJSTest.cpp b/WebWidgets/ExtJS/testsuite/src/ExtJSTest.cpp index 0bf0de436..d84c56fec 100644 --- a/WebWidgets/ExtJS/testsuite/src/ExtJSTest.cpp +++ b/WebWidgets/ExtJS/testsuite/src/ExtJSTest.cpp @@ -1332,7 +1332,7 @@ void ExtJSTest::testJSEvent() pBut->buttonClicked.add(jsDelegate("someFunction2(obj)")); pBut->buttonClicked.add(jsDelegate("hello(obj){alert('Click');}")); //hello must get renamed to function std::ostringstream out; - Utility::writeJSEvent(out, "clicked", pBut->buttonClicked.jsDelegates()); + Utility::writeJSEvent(out, "clicked", pBut->buttonClicked.jsDelegates(),0, false); std::string result(out.str()); static const std::string expected("'clicked':" "{" @@ -1363,7 +1363,7 @@ void ExtJSTest::testJSEvent2() pBut->buttonClicked.add(jsDelegate("someFunction2(obj,o2)")); pBut->buttonClicked.add(jsDelegate("hello(obj){alert('Click');}")); //hello must get renamed to function std::ostringstream out; - Utility::writeJSEvent(out, "clicked", pBut->buttonClicked.jsDelegates()); + Utility::writeJSEvent(out, "clicked", pBut->buttonClicked.jsDelegates(),0, false); std::string result(out.str()); static const std::string expected("'clicked':" "{" diff --git a/WebWidgets/include/Poco/WebWidgets/JavaScriptEvent.h b/WebWidgets/include/Poco/WebWidgets/JavaScriptEvent.h index 530a38aa5..31613b90d 100644 --- a/WebWidgets/include/Poco/WebWidgets/JavaScriptEvent.h +++ b/WebWidgets/include/Poco/WebWidgets/JavaScriptEvent.h @@ -187,13 +187,45 @@ public: return (willDoServerCallback() || !_jsHandlers.empty()); } + void setDelayTime(int millisecs) + /// Sets the delay time for the javascript callback + { + _delayTime = millisecs; + } + int getDelayTime() const + /// Returns the delay time in milliseconds for the javascript callback + { + return _delayTime; + } + + bool getGroupEvents() const + /// Returns if events should be grouped together within the given _delayTime. + /// Every event that occurs within the tiem frame replaces the previous scheduled event + /// and restart the _delayTime wait. + { + return _group; + } + + void setGroupEvents(bool group) + /// Sets if events should be grouped together within the given _delayTime. + /// Every event that occurs within the tiem frame replaces the previous scheduled event + /// and restart the _delayTime wait. + { + _group = group; + } + private: JSDelegates _jsHandlers; ServerCallback _serverCallback; /// Set to SC_YES if a server callback should be done always std::size_t _callbackPos; /// Sets when the server callback should happen (the number defines how many jsHandlers are executed before the server callback) std::string _onSuccess; /// code to execute when the server callback succeeds std::string _onFailure; /// code to execute when the server callback fails + int _delayTime; /// delay Time in millisecs + bool _group; + /// defines if events should be grouped together. + /// Requires a _delayTime greater zero, replaces an event within the delaytime with its newer version + /// Only effective for Javascript side of the event! };