jQuery mobile.changePage returns to first page after initial changePage - jquery-mobile

Here's a problem only with web browsers on the computer, in other words it's not a problem on smart phones as an app.
I updated my jquery mobile framework to the latest release, and i'm trying to log into my account which loads other pages, but as soon as it loads the other pages it loads back to the log in screen. My question is, are there any background functions tied to the changePage function that have changed since 1.0b2'ish release which may affect this?

There have been several changes made to the $.mobile.changePage() function including some deprecations that had code removed for the 1.0 release (latest at the time of this writing).
If you go here: http://jquerymobile.com/blog/, and search for "changePage", you will find some interesting information like this:
Removed support for the alpha signature of $.mobile.changePage() in
preparation for 1.0. Folks now how to use the signature that requires
the toPage (url or element) as the first arg, and options object as
the 2nd. See the events API documentation and commit log for more
info.
You could also take a look at the documentation for $.mobile.changePage() and make sure the current documentation fits with how you are currently using the function: http://jquerymobile.com/demos/1.0/docs/api/methods.html
Updated doc link for 1.1.0: http://jquerymobile.com/demos/1.1.0/docs/api/methods.html

Related

List of Promise API in manifest v3

Overview of Manifest V3 states:
Promise support has been added to many methods, though callbacks are still supported as an alternative. (We will eventually support promises on all appropriate methods.)
Is there a list of APIs that has been converted to Promise?
For example, the following runs into error:
chrome.contextMenus.removeAll()
.then(() => console.log('done'));
// Uncaught TypeError: Cannot read properties of undefined (reading 'then')
I'm not aware of such a list but the support status for a given method will be shown in an IDE (via a tooltip or a method preview or a "Go to definition" command) if you install the official chrome-types package. Don't confuse it with #types/chrome by DefinitelyTyped offered in many IDE by default. The important difference is that the official package is autogenerated from the source code of Chromium, so it should reflect reality, although theoretically their crawler may have bugs.
To see which version of Chrome added the support there's no convenient method yet, so you'll have to check the source code directly and use the Blame feature inside.
Example 1, chrome.contextMenus.removeAll. Search for the method name removeAll using an expression like \bremoveAll\b file:extension.*(json|idl)$ (\b means boundary like a space or a doublequote), you'll see a file named "context_menus", click it, and look at the definition. Only callback is there, no async or Promise, which means it's not converted yet.
Example 2, chrome.tabs.sendMessage. The definition says returns_async, i.e. it supports Promise.
Click the Blame button in the top right corner.
When the panel loads, hover the title of a block inside that corresponds to returns_async line.
You'll see a bubble with the latest change, at this moment it's "Add promise support to SendMessage native hooks", which luckily describes the thing we look for. Otherwise you would have to dig further by clicking "View blame prior to this change".
Right-click the link "Commit xxxxxxx", and copy it, then paste in the addressbar and replace everything except the last long id with chromiumdash.appspot.com/commit/ so in our example it'll be
chromiumdash.appspot.com/commit/2cfa204a0da496b42c3a148d014df4aef45c43fc
The linked page says it's Chrome 99, so it'd be reasonable to add "minimum_chrome_version": "99" in manifest.json to ensure that users of older browsers won't install the extension and won't receive it in an automatic update. In case you really want to support users of older browsers you'll have to use this method in callback mode or apply your own promisifier.

Unable to effectively use Google Tag Manager with Turbolinks

I'm using Google Tag Manager with a Rails 4.2 app with turbolinks. I'm completely stumped and am completely unable to use Google Tag Manager effectively with turbolinks.
Google tag manager seems to repeatedly sense new page loads (the <body> tag getting replaced) as new installations of google tag manager. When I look at my Google tag assistant recordings I just see an endless sea of Green Tags for Google Tag Manager.
Anyone have any leads on resources where I can figure out how to use it effectively?
I've looked at Googletagmanager with Turbolinks which seems to be slightly dated, but also doesn't solve my problem of errant installations.
Replacing the tag will may all kinds of side effects (as you now realize, one being that the code is re-initialized and fires gtm.js events), so I suggest you drop the noscript part and move the rest to the head - I don't really know turbolinks (or RoR), but according to this article turbolinks will not reload the head.
Unfortunately there still might be side effects in an SPA since all items pushed to the dataLayer will just stay there. You might want to consider reseting the dataLayer when you load new content:
window.google_tag_manager[{{Container ID}}].dataLayer.reset();
Where {{Container ID}} is (obviously) the GTM-XXX id for your container. Don't just over the dataLayer variable with an uninitialized array (dataLayer = []) since GTM adds some methods to the dataLayer variable that will get lost if you overwrite it, and your GTM instance will stop to work.

Display options.xul programmatically

I have an xul overlay based Firefox Add-on that works. It has inline options defined in content/options.xul and they display/function correctly when the user goes to Firefox->Add-ons->Extensions->{The Name of My Extension}->Options
The question, can I a create a button on my Add-on that will launch my options either by taking the user to Firefox->Add-ons->Extensions->{The Name of My Extension}->Options with one click or by launching a dialog based on options.xul?
Right now I am maintaining a separate options.html and options.js that gets and sets the same settings that options.xul handles when the user navigates there via the Firefox button but I would much rather dump options.html and options.js and only maintain my main.js and options.xul.
Any comments or code examples will be greatly appreciated.
This is easiest to do via a global function BrowserOpenAddonsMgr() defined in the browser window, like this:
BrowserOpenAddonsMgr("addons://detail/" + encodeURIComponent(addonID));
This function takes care of focusing the existing add-ons tab if there is one or opening a new tab. It will not scroll down to the options however which is an issue if the add-on has a lengthy description. Starting with Firefox 12 this can be solved by adding "/preferences" to the view identifier:
BrowserOpenAddonsMgr("addons://detail/" + encodeURIComponent(addonID) + "/preferences");
With older Firefox versions you are out of luck (and you shouldn't use this suffix there, it won't work). The other issue is that there can be a lengthy "loading" phase where the add-ons manager fetches metadata for all extensions.

FireFox 6: implementing nsIProtocolHandler

Has something changed in Firefox 6 so I can no longer add my nsIProtocolHandler (and nsIChannel) implementation from an add-on just by registering it under a contract like #mozilla.org/network/protocol;1?name=myscheme?
I've checked all the interfaces I use if any changed (judging by a new
UUID), but I don't get a call to my getFactoryProc I list in NSModule,
like I did before.
Do I need to add a category (like http-startup or something?) or is
something else wrong?
(the code that worked in firefox 3.6 is still here I haven't committed
the new code yet...)
Update: I've logged this as a bug.
Update: Okay, I figured this out. See https://bugzilla.mozilla.org/show_bug.cgi?id=656331. Basically you need to export the right kVersion value in your module or the library will be unloaded immediately after it is loaded (i.e. the behavior you are observing). This behavior is new as of Firefox 5.
If you haven't updated to Firefox 4 yet then you need to change the way that you register your XPCOM component. See https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0. The sections on JS components or binary components are relevant depending on whether your component is implemented in JS or C++.

Is History API broken on iOS? (Location bar doesn't update on pushState)

Filing this under the either the I Can't Believe No One Noticed This Before or the I Must Be Missing Something categories:
It appears that if you do a simple window.history.pushState on iOS, the location bar doesn't update unless it is in response to a user gesture. The state itself does get pushed (as you can see by hitting the back button button).
Here's is the tiniest test-case I could come up with recreate the issue:
http://thelink.is/history-api-ios-bug
On a desktop browser that supports the History API, you should see the URL in the location bar change to /0, /1, etc., every second. On iOS – tested with iPhone (running iOS 4.3) and iPad (running iOS 4.3.3) – the location bar doesn't update but hitting the back button will take you the correct previous location (which will 404 on the test-case since there's no back-end logic to handle those URLs).
Thoughts? Workarounds? A shoulder to cry on and hugs?
UPDATE: this issue was fixed in iOS 5.
So the bottom line is that iOS has added its own security around the history API, meaning that you can't use script to change the url. Only a user action can allow the history API to change the url - i.e. a click - as per Aral's example.
The workaround is to uses a hash (aka fragment identifier) on the url.
Instead of the history.pushState we'll just change the location:
var i = 0;
var locationUpdateInterval = setInterval(function(){
window.location.hash = i;
i++;
}, 1000);
To capture the event either when something changes the that location in the iOS app or if they have permalink to a particular page/panel in your app:
// named function on purpose for later
function hashchange() {
var pageId = location.hash.substr(1); // drop the # symbol
// do something with pageId
}
window.onhashchange = hashchange;
// onload - if there's a hash on the url, try to do something with it
if (location.hash) hashchange();
It's pretty poor that we can't use the pushState/popState on iOS, but it's the same security as not being able to trigger fullscreen video unless the user initiates the action, which is the same as downloading video or audio content on iOS - you can't script it, the user must start it (somehow or another).
Just as a note about Android - the problems are pretty similar, so this (should) also work as a workaround for Android.
If you want desktop support, most browsers support onhashchange but, yep, you guessed, IE is lacking behind - so you can polyfill that bad boy in (though requires jQuery...): http://benalman.com/projects/jquery-hashchange-plugin/
Hope that helps.
Works fine for me when using: https://github.com/browserstate/history.js - this also fixes many other cross browser bugs with the HTML5 History API.
As of v1.7, here are the bugs it solves:
History.js solves the following browser bugs:
HTML5 Browsers
Chrome 8 sometimes does not contain the correct state data when traversing back to the initial state
Safari 5, Safari iOS 4 and Firefox 3 and 4 do not fire the onhashchange event when the page is loaded with a hash
Safari 5 and Safari iOS 4 do not fire the onpopstate event when the hash has changed unlike the other browsers
Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a replaceState call / bug report
Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions / bug report
Google Chrome 8,9,10 and Firefox 4 prior to the RC will always fire onpopstate once the page has loaded / change recommendation
Safari iOS 4.0, 4.1, 4.2 have a working HTML5 History API - although the actual back buttons of the browsers do not work, therefore we treat them as HTML4 browsers
None of the HTML5 browsers actually utilise the title argument to the pushState and replaceState calls
HTML4 Browsers
Old browsers like MSIE 6,7 and Firefox 2 do not have a onhashchange event
MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function)
Non-Opera HTML4 browsers sometimes do not apply the hash when the hash is not urlencoded
All Browsers
State data and titles do not persist once the site is left and then returned (includes page refreshes)
State titles are never applied to the document.title
(Update: Just saw that Remy answered too – read his in-depth answer, above, instead.)
Remy provided a workaround for this issue on Twitter.
Basically, if you change the location.hash, the address in the location bar updates. However, this does create a separate entry in the history (which doesn't work for what I'm trying to achieve). The workaround I'm implementing is to use hash-bang URLs for iOS and regular ones for other platforms until the iOS bug is fixed. This is definitely not ideal and I hope that Mobile Safari on iOS will start behaving like Chrome, Firefox and Safari on desktop.
Here's what I found:
When the pushed location contains a hash symbol, the adressbar will be updated.
So this will work:
window.history.pushState(data, title, 'a/new/url#');
But the window.location object will not be updated so you need to save the pushed url into a variable and use that instead of window.location if you need the pushed location.
Tested on Safari for Android.
I found a hack that kinda works. It turns out that if you change the hash right after history.pushState the location bar gets updated. Like:
window.history.pushState(data, title, 'a/new/url');
window.location.hash = 'new';
changes the location bar to http://example.com/a/new/url#new. Which introduces another problem because the hash becomes it's own history entry. So you'll need to listen to onHashChange anyway.
It's a bit complicated, but there are some people who really, really hate hashbang urls and are very vocal about it. So it's worth it.

Resources