with rearranged js and helper functions to avoid browser incompatibilities