Git Product home page Git Product logo

crosstab's People

Contributors

alias-mac avatar cesarandreu avatar chadly avatar davidxi avatar gitter-badger avatar imsnif avatar kucheruk avatar scaryzet avatar tejacques avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crosstab's Issues

Enhance documentation

README should be updated to include more comprehensive documentation, and additional examples should be added.

Change the way notSupported works

If crosstab.notSupported is true, crosstab should work by only handling events processed on it's own tab, and always believing that it is the master tab, and that it is the only tab. This way, logic doesn't need to be duplicated, you can always rely on the events firing from within a tab. This will also allow crosstab to be used on mobile without issue, it basically just acts as a fancy event emitter.

Writing "null" to LocalStorage causes a "Cannot read property 'id' of null" error to be thrown

In onStorageEvent, it is optimistically parsing values as JSON and then assuming that the result is an object. This causes "eventValue" to be "null" and then "eventValue.id" to fail.

There are different ways of solving this, but I would have thought that crosstab should be checking the "key" property of all incoming StorageEvents and only processing ones that are relevant to crosstab.

Is using:

if (event.key.indexOf('crosstab') !== 0) return;

a possible fix?

Uncaught Error: crosstab not supported: frozen tab environment detected" in IE9 browser

Hi tejacques, I am using your cross tab js. This issue occurs on Windows 7 IE9. As higher version of IE on windows 7 machine is IE9.
Steps to reproduce:-

  1. Take Windows7 OS machine.
  2. Host your demo sample code into IIS.
  3. Now try to browse your page in IE browser.
  4. Change browser mode to IE9 and Document mode to IE9 standards.
  5. Open another tab in same browser
  6. Now try to broadcast msg from first tab to second tab it will give error : "Cross tab not supported :- Frozen tab environment detected".
    Can you please tell me how to resolve this issue.

Research: Polyfill / Shim to get storage events to work correctly on IE8

There are a few implementations of such shims available on the internet, but it's not clear to me whether there can be data lost due to race conditions. If there is a way of shimming this on IE8 in a way that is fully compliant and not subject to race conditions then it we should support and test that shim.

Prerender mode problem

Here is what i've found.

Say we have 2 pages: http://localhost:3000 and http://localhost:3000/index2.html. Each of these pages runs a script which 'unshifts' current url into array which is in localStorage. When we first open http://localhost:3000 we have [http://localhost:3000]. After navigating to http://localhost:3000/index2.html array becomes [http://localhost:3000/index2, http://localhost:3000] and so on. But some browsers (I tested in Google Chrome 47 and Safari 9) prerender pages. So when we type 'http://local' in address field, then choose http://localhost:3000/index2, change out mind, delete /index2 and go to http://localhost:3000 instead we have this: [http://localhost:3000, http://localhost:3000/index2, http://localhost:3000/index2, http://localhost:3000]. It happens because script on http://localhost:3000/index2 was executed in background mode.

I noticed that in same cases crosstab decides that my tab is not master though I only have one tab open. After studying this problem by looking at localStorage I found out that when I open new tab another nonexistent tab is already set as master. After some time (3 secs if I'm not mistaken) my tab regains master status (obviously because of keepalive loop) and everything is ok. It happens in 90% of cases. But sometimes frozen-environment problem occurs.

I think that this problem is caused by page prerender. I was able to solve it by removing frozen tab detection (here https://github.com/tejacques/crosstab/blob/master/src/crosstab.js#L753 and here https://github.com/tejacques/crosstab/blob/master/src/crosstab.js#L646-L653). Instead I forced new master tab reelection.

I suggest using page visibility API (https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) and perform side effects only when page is not in prerender mode.

Opening a number of tabs at once can result in no Master

Repro:

  1. Open a number of tabs (~5) with the supplied sample page crosstab/samples/index.html
  2. Using IE(10) right-click one of the tabs and select "Refresh All" from the context menu

You may need to do this a few times to see the behaviour, but I usually get it within a few tries. Once in this mode of no Master performing subsequent "Refresh All"s does not fix the problem. One of the tabs appears to think it is Master (but is not reflecting that state) as refreshing the individual pages one by one eventually fixes the issue (on a specific tab).

While this may not be a typical user scenario I have seen it in production when a number of pages load at once (automatic logon after re-authentication).

I've also noticed that under heavy load (JS intensive pages) localStorage can become a bit flaky with the timing of events, causing similar issues with the election process (this is a bit hard to show repro steps for).

Edge support using service workers

Edge supports service workers as of Edge 17. This should finally make it possible to support Edge, as it'll be possible to pass messages through a service worker instead of through local storage.

Just wondering if this is something you'd be interested in implementing / accepting a PR for, or if the project is pretty much unmaintained now?

Is it possible to process a setInterval() call only to the active tab/browser?

is it possible to have only the active tab execute a setInterval() function only on the active tab?

so if I am on tab A then execute setInterval() function which triggers an API page. then when I open tab B then the setInterval()on tab A will need to stop and the function on tab B starts.

is this possible and how?

thanks you

Need ability to set a custom master tab

I think it would be quite helpful to add the feature of setting a custom master tab from any of the other tabs. One of the use cases would be when someone wants one of the non-master tabs to open a websocket and disconnect from the master tab.

For example, in my case, I want to limit the number of sockets my application opens. But at the same time, I want to avoid cases where user experience is affected due to closed sockets. So, by default, my app opens the connection on the master tab. But when the user interacts with one of the other tabs, I would want to make it a master tab and then open a socket. At the same time, previous master tab will close the socket.

Copyright statement

Hi,

You included the Apache license but I can't seem to find your copyright.
(See 'How to apply the Apache License to your work.' of the license)

Would you be able to add that?

Thank you

No MASTER_TAB re-election on Firefox iframe

No reelection occurring after MASTER_TAB refresh on a iframe.

Steps for reproducing:

  1. Open Firefox 40;
  2. Open 2 tabs with Javascript running on an iframe;
  3. Refresh the master tab;

Result:

  • There are no MASTER_TAB elected. The MASTER_TAB value on localStorage is pointing to a not existent tab:
{
  "14488945006270009571866": {
    "id": "14488945006270009571866",
    "lastUpdated": 1448895188388
  },
  "MASTER_TAB": {
    "id": "14488944316952140456572",
    "lastUpdated": 1448894501270
  },
  "14488945024330039719292": {
    "id": "14488945024330039719292",
    "lastUpdated": 1448895189539
  }
}

localStorage broken in IE/Edge on Windows 10

localStorage currently has several issues and is not reliable in IE/Edge on Windows 8 and 10. Microsoft will need to fix this before localStorage can be used reliably. There might be an alternative to use with IndexedDB and polling, but it's not as performant.

In Chrome 46 on OSX sometimes frozen tab environment is detected

Is it possible that the detection sometimes has false positives for some reason, or that the timeout is simply too low? Maybe the detection mechanism is fuzzy or racing?

Could it be possible to make this automatic detection of "frozen tabs" optional?

It could be let to the application how to deal with the fact that a broadcast call might not reach all tabs eventually or with a substantial delay.

Firefox: Initial tab fetch excepts if access to localStorage is disabled.

Found because of mozilla/fxa-content-server#1848.

Background

Firefox lets a user block access to localStorage & sessionStorage through a browser preference independently of cookies. If the browser preference is set to disable access to localStorage, the initial tab fetch excepts.

STR

  1. Open Firefox
  2. In a new tab, open about:config
  3. Set value of dom.storage.enabled to false
  4. Load crosstab library.
  5. Watch the explosion.

Line 241: var json = localStorage.getItem(key);
TypeError: localStorage is null

Expected

Startup completes, but crosstab.supported is false

Actual

The above exception

Example doesn't work

Example doesn't work - please check it. Browser Chrome - errorText - crosstab not supported - without explain. FF - ok

Expose crosstab.isMaster?

I see in the code you have an isMaster function that is not being used anywhere. I was wondering why that is not exposed. It seems like it would be useful.

I'm trying to make my app only open a websocket connection on the master tab. Maybe I am approaching it wrong. My idea was to do something like this:

var crosstab = require("crosstab");

if (crosstab.isMaster()) {
  //open websocket connection & broadcast on crosstab when websocket messages come in
} else {
  //listen for crosstab events
}

How would I go about making this work?

Enable async loading and host crosstab on cloudflare/cdnjs

This is a pretty simple addition and can be done similarly to how analytics and gpt work.

Loading Tag

<script>
    (function (window, document, script, url, crosstab, scriptTag, firstScriptTag) {
        window[crosstab] = window[crosstab] || (function (fn) {
            (window[crosstab].q = window[crosstab].q || []).push(fn);
        })();
        scriptTag = document.createElement(script);
        scriptTag.async = true;
        scriptTag.src = url;
        firstScriptTag = document.getElementsByTagName(script)[0];
        firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);
    })(window, document, 'script', '//url.to/crosstab.js', 'crosstab');
</script>

This minifies to the following:(this is beautified to be readable but get the point across)

(function(w, d, s, u, c, n, r) {
    w[c] = w[c] || function(f) {
        (w[c].q = w[c].q || []).push(f)
    }(),
    t = d.createElement(s),
    t.async = !0,
    t.src = u,
    r = d.getElementsByTagName(s)[0],
    r.parentNode.insertBefore(t, r)
})(window, document, 'script', '//url.to/crosstab.js', 'crosstab');

Change to crosstab.js

When crosstab is setting up, it should look for a global crosstab variable, and try to grab the cmds out of it. If present, it should call crosstab(fn) for each one.

This isn't a critical feature, but it's nice to have

Can data-value persist across opened tabs/windows ?

Hi,

We ran into an issue when language is changed from one tab, it is not being reflected in another already opened tab. We are using below code to set language in cookie.

if (angular.equals(addcookie, "Yes")) {
$cookieStore.put('lang', langKey);
}

Could you please explain how do we use your extension in AngularJS in order to reflect the language change across all the opened tabs/windows ? Also does it work with open windows too apart from open tabs ?

Browser Tabs?

Unless I'm missing something, crosstab doesn't actually open/enable communication between browser tabs. Is that right?

The sample seems to only add a Div to the same tab you're on. I was hoping for an effective way to coordinate two different browser tabs, one spawned by another calling window.open().

I'm going to play with it some more, as maybe the sample doesn't illustrate this functionality even if it does exist.

becomeMaster vs tabPromoted vs tabUpdated

I notice that the becomeMaster event doesn't seem to work as expected, it doesn't necessarily fire when a tab becomes master.

I also notice that your sample crosstab\samples\index.html doesn't use the becomeMaster event, instead it looks at the tabPromoted and tabUpdated events and updates the state of the UI (after a setTimeout) to the new state.

I would have thought the becomeMaster event would be the only event I would need to subscribe to for knowledge of who the master is (unless I specifically wanted to know when a tab was updated).

Firefox: Startup exception if cookies are disabled.

Link to #2

Background

Similar to #2, if the user disables cookies in Firefox, then access to localStorage is also disabled. As soon as the library loads and fetches a reference for window.localStorage, an exception is thrown.

STR

  1. Open Firefox
  2. Open user preferences via about:preferences#privacy
  3. In History, change Remember History to Use custom settings for history
  4. Uncheck Accept cookies from sites

Expected

Startup completes and crosstab.supported is false.

Actual

8 var localStorage = window.localStorage;
SecurityError: The operation is insecure.

crosstab not supported error in Crhome v41.0.2272 - Windows 7

Hi,
I'm not sure why this happening, I'm using crosstab in my application. It works fine initially, but when the page load increases or if my application get crashed, crosstab is not working. It throws "crosstab not supported" error. Even after restarting the browser this issue is coming.

Steps to reproduce:

  1. Open a page which uses crosstab
  2. Open console, and run a infinite loop, now the application will crash.
  3. Restart the browser and open the page
  4. Observe the error

"crosstab not supported" when using with Browserify

Uncaught Error: crosstab not supported: localStorage not availabe, addEventListener not available, localStorage.setItem not allowed

The context variable this passed to the factory function refers to module.export instead of window object in Browserify environment.

2bf8403 seems to cause this so the problem exists only in 0.2.8

Add higher level functionality to API

Currently thinking something along the lines of this:

crosstab({ event, data, destination, callback, timeout })

It could be used like this:

Setup

crosstab.on('PING', function(message, reply) {
  if (message.destination === crosstab.id
    || (!message.destination && crosstab.isMaster())) {
    reply('PONG'); // replies directly to this message
  }
});

It's still a little cumbersome to indicate that this should only handle direct messages, or if it is the master. This could be resolved by having some helper defaults:

crosstab.onDirect(event, fn(message, reply));
crosstab.onMaster(event, fn(message, reply));
crosstab.on(event, fn(message, reply), type=DIRECT | MASTER);

Call

crosstab({
  event: 'PING',
  callback: function(response, err) {
    if(!err) {
      console.log("Received: ", response.data, " from: ", response.origin);
    } else {
      console.log("Error: ", err);
    }
  },
  timeout: 1000
});
crosstab.broadcast(event, data, destination, callback = null, timeout = infinity);
crosstab.broadcast(event, destination, callback = null, timeout = infinity);
crosstab.broadcast(event, callback = null, timeout = infinity);

crosstab.broadcastMaster(event, data, callback = null, timeout = infinity);
crosstab.broadcastMaster(event, callback = null, timeout = infinity);

This will greatly reduce boilerplate and increase ease of use for creating tools based on crosstab.

It also makes it easy to create a Promise wrapper using the callbacks.

Add tests

Look into using mocha/phantomJS for testing.

No assumed master after tabs refresh

I've tested reloading 4 tabs at the same time, and in the end I've got the following result:

1st Tab - 14455266368170676283082
tab1

2nd Tab - 14455266379341197551397:
tab3

3rd Tab - 14455266379810761529770:
tab4

4th Tab - 14455266385181543926377:
tab2

So, every tab thinks that 2nd tab is the master, except the 2nd tab itself and the localStorage.
So nobody is assuming the master work.

On localStorage (crosstab.TABS_KEY) there's only 2 tabs registered:

{
  "id": "14455266368170676283082",
  "data": {
    "14455266368170676283082": {
      "id": "14455266368170676283082",
      "lastUpdated": 1445526636819
    },
    "MASTER_TAB": {
      "id": "14455266368170676283082",
      "lastUpdated": 1445526636819
    },
    "14455266379341197551397": {
      "id": "14455266379341197551397",
      "lastUpdated": 1445526637942
    }
  },
  "timestamp": 1445526638301
}

I'm thinking that the problem could be on localStorage concurrency (everyone is writing and just the last one result wins).

I'm using crosstab version v0.2.11 on Chrome 46.

Chrome & IE now broken?

I have a very basic implementation of this using on 1 page:

crosstab.on('issue-a-item', function(data) { console.log('Called Crosstab'); $('#barcode-search').val(data.data.barcode); lookupItem(true); });

on another page:
$('body').on('click', '.issue-this-item', function(e){ e.preventDefault(); var tr = $(this).closest('tr'); var row = window.LaravelDataTables.dataTableBuilder.row(tr); var data = row.data(); crosstab.broadcast('issue-a-item', { 'barcode' : data.barcode }); setTimeout(function(){ window.close(); },500); });

Still works on firefox but on chrome and IE (IE broke last year) it now gives me the Frozen Tab error on clicking "issue-this-item".

Is there any alternatives to crosstab because I need this to work and I see from another issue you have said that you don't have the motivation to work on this.

Improve events

Currently the event emitter doesn't fire listeners in the order they were added. Could potentially just swap to node's event emitter.

Detect frozen tab environments and drop support for crosstab when detected.

Currently frozen tab environments, where only the active tab is executing javascript, are detected using the user-agent. There is no feature or group of features than can be used to cover all scenarios, so in order to detect this, we'll have to get inventive.

Change crosstab from an object to a function, which takes an object / function that will be executed once crosstab setup is complete.

When a tab comes up, check if localStorage crosstab.frozenTabEnvironment is set to true. If it is, crosstab is not supported.

Otherwise check the user-agent against known frozen tab devices. If there is a match, set localStorage crosstab.frozenTabEnvironment and set crosstab to not supported.

Otherwise check if there is another tab registered as master. If there is attempt to PING the master. If we do not hear back within a short timeout (<50ms), then set localStorage crosstab.frozenTabEnvironment to true. When we hear back from the master, we will fire the crosstab.setupComplete event.

Otherwise register as normal, and fire the crosstab.setupComplete event, but check crosstab.frozenTabEnvironment when updating. If it is set, disable support.

Anywhere in code where you want to use crosstab, you should always check something in the style of:

function crosstabSupported() {
  // code here will execute once crosstab setup is complete if crosstab is supported.
}

function crosstabUnsupported() {
  // code here will execute once crosstab setup is complete if crosstab is unsupported
}

if (window.crosstab) {
  crosstab(function() {
    if (crosstab.supported) {
      crosstabSupported();
    } else {
      crosstabUnsupported();
    }
  });
} else {
  crosstabUnsupported();
}

This method will fail if the master tab is currently under enough load where 50ms is not sufficient to respond to a PING, however this should never practically occur. The one-time 50ms penalty for nondetected frozen tab environments should not be prohibitive

Broken inter-tab communication in IE when tab is an iframe

Digging into it revealed that localStorage in IE seems to be absolutely broken by design.
http://kntajus.blogspot.com/2014/08/local-storage-fundamentally-broken-in.html
https://connect.microsoft.com/IE/feedback/details/811546/ie11-localstorage-events-fire-twice-or-not-at-all-in-iframes
Even better!
https://connect.microsoft.com/IE/feedback/details/812563/ie-11-local-storage-synchronization-issues

Rising the PING_TIMEOUT or even all the timeouts didn't work.
So here's a starting point to see the problem:

  • goto http://dev.modern.ie/tools/vms/#downloads and get a virtualbox image of IE11 on win8.1(IE10 is broken too, I guess)
  • import to virtual box and launch
  • put 10.0.2.2 host1 and 10.0.2.2 host2 to c:/window/system32/drivers/etc/hosts (for this launch Notepad as Admin)
  • add host in ng-src of iframe in index.html
    ng-src="http://host1:9000/samples/index.html"
  • open the IE, goto http://host1:9000
  • open dev tools(F12), and set the document mode to Egde or IE10
  • start adding tabs-iframes, see if everything is ok
  • open another tab with http://host1:9000 and try to add more iframes
  • open another tab with http://host2:9000 and try to add more iframes
  • see how much I hate IE :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.