User tests: Successful: Unsuccessful:
In the pull request a couple methods which allow to work with Events, and do AJAX request.
That allow to write some basic JavaSript without additional JavaSript library.
Add in index.php
of Isis template the button:
<button id="my-button">button</button>
And in template.js
:
Joomla.domReady(function(){
var button = document.getElementById('my-button');
function myClickHandler (event){
console.log('You just clicked', event.target || event.srcElement);
testRequest();
button.removeEventListener('click', myClickHandler);
button.addEventListener('click', function(){
alert('Click me again!');
});
}
function testRequest(){
Joomla.request({
url: 'index.php?option=com_content',
onBefore: function(xhr){
console.log('Before:', xhr.readyState);
},
onSuccess: function(response, xhr){
alert('Page title is ' + response.match(/<title[^>]*>([^<]+)<\/title>/)[1]);
},
onError: function(xhr){
alert('Error:' + xhr.status + ' ' + xhr.statusText);
}
});
}
button.addEventListener('click', myClickHandler);
});
then click on the button:
'index.php?option=com_content
"Page title is Articles ..."Click me again!
Then try change url: 'index.php?option=com_content',
to url: 'index.php?option=com_foobar',
.
After first click you should get an alert with "Page not found"
I seen stuff where jQuery used only for catch domReady
, and load a whole library just for it is a bit strange
Joomla JavaScript framework
That would be fun
I honestly don't see the need to invent new APIs and wheels to do stuff that is already being done with existing code and resources, even if it does mean a dependency to a library that people seem to hate being loaded for some reason. I'm all for using native JavaScript where it makes sense and where it doesn't create overly complex code (knowing we're still supporting IE8), but right now I'm not convinced that a homegrown replacement for jQuery(document).ready()
or jQuery.ajax()
is in our best interests. Maybe during the 4.0 development cycle where older browser support can be dropped that opinion could sway, but right now I think our time is better invested elsewhere.
Honestly in general I'm not a fan of how many times I see it suggested that Joomla writes its own solution when there is already a functional and supported solution either already shipped with Joomla or available to be easily consumed. Ya there's some risk with including third party dependencies, but the more we build in house and the more Joomlaisms we create the harder it is to maintain our code base or have it in a state where folks can easily implement it. Even worse is when the suggestion to just fork the third party resource and maintain it ourselves comes around.
I agree with @mbabker when it says there are several cases were Joomla writes its own solution when there is already a functional and supported solution either already shipped with Joomla or available to be easily consumed
but for me this is not the case.
I agree with @Fedik on this, there are several case jQuery is only used for events or ajax calls and i prefer to always use a vanilla js aproach. For js performance reasons a vanilla js is always better than using jQuery.
I will test this when i have time.
@Fedik tested your example and works fine, but i also tried to add this and didn't totally work:
JFactory::getDocument()->addScriptDeclaration("
Joomla.addListener(window, 'load', function ()
{
var xhr = Joomla.request({
url: 'index.php?option=com_foobar',
onBefore: function(xhr){ console.log('Before:', xhr.readyState); },
onSuccess: function(response, xhr){ alert('Page title is ' + response.match(/<title[^>]*>([^<]+)<\/title>/)[1]); },
onError: function(xhr){ Joomla.ajaxErrorsMessages(xhr); }
});
});
");
Js Console log
Before: 1
core.js:1 GET /administrator/index.php?option=com_foobar 404 (Component not found.)
core.js:1 Uncaught TypeError: Cannot read property 'replace' of undefined
Is something wrong with my code or other thing?
it because Joomla.JText._('JLIB_JS_AJAX_ERROR_OTHER')
do not return the translation, because it do not exists.
you also need to call: JText::script('JLIB_JS_AJAX_ERROR_OTHER')
if I right
and use Joomla.renderMessages(Joomla.ajaxErrorsMessages(xhr));
sorry my mistake, was sleeping before this works fine!:
// Load JavaScript message titles
JText::script('ERROR');
JText::script('WARNING');
JText::script('NOTICE');
JText::script('MESSAGE');
// Add strings for JavaScript error translations.
JText::script('JLIB_JS_AJAX_ERROR_CONNECTION_ABORT');
JText::script('JLIB_JS_AJAX_ERROR_NO_CONTENT');
JText::script('JLIB_JS_AJAX_ERROR_OTHER');
JText::script('JLIB_JS_AJAX_ERROR_PARSE');
JText::script('JLIB_JS_AJAX_ERROR_TIMEOUT');
JFactory::getDocument()->addScriptDeclaration("
Joomla.addListener(window, 'load', function ()
{
var xhr = Joomla.request({
url: 'index.php?option=com_foobar',
onBefore: function(xhr){ console.log('Before:', xhr.readyState); },
onSuccess: function(response, xhr){ alert('Page title is ' + response.match(/<title[^>]*>([^<]+)<\/title>/)[1]); },
onError: function(xhr){ Joomla.renderMessages(Joomla.ajaxErrorsMessages(xhr)); }
});
});
");
I have tested this item
Works fine and IMHO a much needed PR!
This will definitely need to be tested in IE8. If I rightly remember, don't older IE versions need a small pollyfill for functions like removeListener
and addListener
?
it already should work in IE, but testing is required
@Fedik I think I agree to some extend with @mbabker, but that doesn't mean that I disagree completely with this PR.
My point of view is that Joomla should not start creating own functionality for something that is already given in ecmascript6. So let's say for addEventListener, this works for every modern browser except IE8! OK then, let's use that and polyfill the missing part for IE. At the end we end up at the same result BUT we re using the STANDARDS from ECMA and probably none of the PLT (in their right mind) should not object on that (I mean ECMA6 is already killing jQuery, open your eyes and don't put the project to the same position as with mootools/jquery)!
Recap: instead of introducing Joomla's own weird functions let's embrace the ECMA6 and fill the gaps for IE8 (for as long as this browser exists as a supported thing from the project)
as usual the real problem here is IE ... without that browser most jquery scripts could be replaced with vanilla js.
@andrepereiradasilva I am just saying let's use vanilla js AND polyfill what IE is missing. In matter of fact we don;t even have to code that as those polyfills already exist
@andrepereiradasilva we could even use JBrowser to add the polyfill only for IE
do you mean something like if ie load ecma6shim.js?
The same way we do it for html5shim ?
ok, I can remove Joomla.(add/remove)Listener
and just add fallback for IE for Element.(add/remove)EventListener
about polyfill, it can be only with client side check, because JBrowser will fail for 100% when Joomla! behind caching proxy.
I have removed Joomla.(add/remove)Listener and added very simple fallback for IE for Element.(add/remove)EventListener
, but it is pour fallback
There still a small difference in event object. In theory it should be enough for our basic needs but, it like a half-worked solution.
So no idea, maybe can leave ajax
and domReady
, but remove other event stuff. Or include one of existing polyfill in the core, but it doesn't sounds as good idea
reggarding events, if i understand correctly for vannila js you use something like this
document.addEventListener('DOMContentLoaded', function() {
this.getElementById('myElement1Id').addEventListener('click', function() {
alert('clicked 1');
});
this.getElementById('myElement2Id').addEventListener('click', function() {
alert('clicked 2');
});
this.querySelector(".myclass").addEventListener('click', function() {
alert('clicked 3');
});
});
For what i understand this doesn't work only in IE8 right?
http://caniuse.com/#feat=domcontentloaded
http://caniuse.com/#feat=addeventlistener
http://caniuse.com/#feat=queryselector (IE8 partial support)
For what i understand this doesn't work only in IE8 right?
yes, and maybe in IE9, not remember
so reggarding events we "just" needd to polyfill (add/remove)eventlistener and domcontentloaded for IE8 and all should work.
ajax is another matter
doesn't this does that? https://github.com/WebReflection/ie8 or https://gist.github.com/chriswrightdesign/7573368 (just an example)
we can include the polyfill only in ie8, like we do for html5shim, something like
<!--[if lt IE 9]><script src="/media/jui/js/ie8polyfill.js"></script><![endif]-->
with that we could use vanilla js for events!
what do you guys think?
unfortunately it will not work that easy, because <!--[if lt IE 9]>..
must be manually added in the template, and we cannot force it
so if template do not contain this then our scripts will be broken in old IE
Doesn't that also happens with html5 js?
and we cannot force it
when we need, we can
$doc->addCustomTag('<!--[if lt IE 9]><script src="/media/jui/js/ie8polyfill.js"></script><![endif]-->');
unfortunately it will not work that easy, because <!--[if lt IE 9]>.. must be manually added in the template, and we cannot force it, so if template do not contain this then or scripts will be broken in old IE
since the code is really small, why not add inside core.js,
and then add it inside an if statement
var userAgent = navigator.userAgent.toLowerCase();
var IEversion = (userAgent.indexOf('msie') != -1) ? parseInt(userAgent.split('msie')[1]) : false;
var isIE8 = IEversion ? IEversion < 9 : false;
if (isIE8)
{
...
}
also a little off topic, maybe we are are adding too many small JS files
@ggppdk - Using @andrepereiradasilva's method above is better than checking the user agent. Also means it doesn't need to manually be added to the template.
Personally, I'd suggest combining all IE8 pollyfills and shivs into 1 JS file and simply use the following in core templates:
<!--[if lt IE 9]>
<script src="/media/jui/js/ie8.js"></script>
<![endif]-->
Either that or park this PR until J4.x when supporting IE8 may not be required in core, but instead the template providers.
also a little off topic, maybe we are are adding too many small JS files
I see no problem with that.
Also, after SPDY, the web is moving to HTTP 2.0 (finaly!!) and HTTP 2.0 does multiplexing of requests so from what i understand there is no bottleneck in a browser downloading a lot of js/css files from the same server.
Yes, ok,
@andrepereiradasilva
you mean add it here ?
https://github.com/joomla/joomla-cms/blob/staging/libraries/cms/html/behavior.php#L87
JFactory::getDocument()->addCustomTag(
'<!--[if lt IE 9]><script src="media/jui/js/ie8polyfill.js"></script><![endif]-->'
);
JHtml::_('script', 'system/core.js', false, true);
Doesn't that also happens with html5 js?
html5 js do not contain any logic we use, it just for browser to help to understand new tags
$doc->addCustomTag()
ignore possibility to override the script, that possible with JHtml::_('script', 'blabla.js')
you mean add it here ?
https://github.com/joomla/joomla-cms/blob/staging/libraries/cms/html/behavior.php#L87
if we use add/removeEventListener + DOMContentLoaded in the core.js ...
What i'm saying is adding a JHtml behaviour to add that custom tag
public static function ie8()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include IE8 polyfill
JFactory::getDocument()->addCustomTag('<!--[if lt IE 9]><script src="/media/jui/js/ie8polyfill.js"></script><![endif]-->');
// Set static array
static::$loaded[__METHOD__] = true;
}
them whenever you use add/removeEventListener + DOMContentLoaded polyfill you call that dependency first.
JHtml::_('behavior.ie8');
or something like this
this will also be good in template managers still want (or need) to support ie8 in Joomla 4.
Yup, that sounds like a good idea.
JHtml::_('behavior.ie8');
should also load html5shiv.js
.
One thing that needs to happen though is, these scripts should be loaded before any other script
One thing that needs to happen though is, these scripts should be loaded before any other script
for that you need to change JDocumentRendererHtmlHead output order
See https://github.com/joomla/joomla-cms/blob/staging/libraries/joomla/document/renderer/html/head.php#L310
What about
JHtml::_('behavior.extend');
or similar ?
in near future version of Joomla the inclusion of IE8 specific stuff will be removed
for me is ok
so for what i understand from this discussion we need to separate things:
So this should be two different PR's since they are not related. @Fedik do you agree?
yes, better to split these things,
I will remove the event stuff from current pull request
Category | ⇒ | JavaScript |
I have tested this item
just removed the events so still ok for the ajax request in core js
I have removed the events stuff, and updated the testing instruction
I have tested this item
Works fine
Status | New | ⇒ | Ready to Commit |
RTC Let's wait for PLT
@andrepereiradasilva if you are about to do that can you use:
$scriptPath = JHtml::_('script', 'media/jui/js/ie8polyfill.js', false, true, true, false, true); // return only path
// Include IE8 polyfill
JFactory::getDocument()->addCustomTag('<!--[if lt IE 9]><script src="' . $scriptPath . '"></script><![endif]-->');
well, find a good polyfill and use condition comment as you suggested,
one of hundert https://github.com/WebReflection/ie8
there also was @dgt41 suggestions
hard to chose
i am not about to do it
. you guys have more knowledge in this than i do.
I fail miserably on copy-paste
:)
it seems that is forked from https://github.com/Financial-Times/polyfill-service/tree/master/polyfills
Yeah Financial-times don;t use native mobile apps instead they use plain javascript. Most of their code is available on github. Thus the polyfill need I guess
and this licence is usable with current joomla policy (i honestly don't have a clue)
MIT should be fine (I have no clue either)
MIT's fine. Otherwise the Symfony code we're shipping would have to come out.
so will this be RTC ?
Status | Ready to Commit | ⇒ | Needs Review |
Status | Needs Review | ⇒ | Ready to Commit |
@andrepereiradasilva ok RTC down to PLT then
Title |
|
RTC
@Fedik Take a look at the sendtestmail tests, they mock the http requests.
Ping me if i should explain more :)
Labels |
Added:
?
|
done, just conflict of minified versions
Status | Ready to Commit | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2016-10-01 14:44:54 |
Closed_By | ⇒ | rdeutz |
Labels |
Removed:
?
|
My first feeling here is do we really want to go the route of writing a Joomla JavaScript framework and be 100% independent of dependencies that we're already loading and shipping? I get the value for some of our other utilities, but replacing
jQuery.ajax()
? Unless we're aiming for a headless CMS in 4.0 (and all of the UI stuff is basically deferred to templates only), this just seems like doing stuff for the sake of doing it.