#StackBounty: #javascript #reactjs #webpack No loading/serving of stylesheets – react

Bounty: 50

I am rendering pages server-side with React router’s StaticRouter.

express.js (server)

const html = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context}>
        <App />
    </StaticRouter>
);

res.status(200).send(`
    <!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
            
${html}
</body> </html> `);

Serving of static files:

app.use(express.static(path.resolve(__dirname, "../dist/client")));

App.js (shared)

import React from "react";
import { Switch, Route } from "react-router";

require("./styles/Main.scss");

export default () => {
    return (
        <Switch>
            ...
        </Switch>
    );
};

index.jsx (client)

import React from "react";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
    <BrowserRouter>
        <App/>
    </BrowserRouter>,
    document.getElementById("app")
);

./styles/Main.scss

.theHeader {
    background-color: #002933;
}

I have 2 webpack configurations, 1 for the client & 1 for the server:

webpack.config.dev.js

const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    devtool: "cheap-module-eval-source-map",
    entry: {
        app: [
            "eventsource-polyfill",
            "webpack-hot-middleware/client",
            "webpack/hot/only-dev-server",
            "react-hot-loader/patch",
            "./client/index.jsx",
        ],
        vendor: [
            "react",
            "react-dom",
        ],
    },
    output: {
        path: `${__dirname}/dist/client`,
        filename: "app.min.js",
        publicPath: "http://0.0.0.0:8000/"
    },
    resolve: {
        extensions: [
            ".js",
            ".jsx"
        ],
        modules: [
            "node_modules"
        ],
    },
    externals: [
        nodeExternals()
    ],
    module: {
        loaders: [
            {
                test: /.jsx*$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            }, {
                test: /.json$/,
                loader: "json-loader",
            }, {
                test: /.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    limit: 8192
                }
            }, {
                test: /.scss$/,
                exclude: /node_modules/,
                loader: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: [
                        "css-loader",
                        "sass-loader"
                    ]
                }),
            }, {
                test: /.css$/,
                loader: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            },
        ],
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            name: "vendor",
            minChunks: Infinity,
            filename: "vendor.js",
        }),
        new webpack.DefinePlugin({
            "process.env": {
                CLIENT: JSON.stringify(true),
                NODE_ENV: JSON.stringify("development")
            }
        }),
        new ExtractTextPlugin({
            filename: "[name].css",
            disable: process.env.NODE_ENV === "development"
        }),
    ]
};

webpack.config.server.js

const ExternalsPlugin = require("webpack-externals-plugin");

module.exports = {
    entry: `${__dirname}/server/server.js`,
    output: {
        path: `${__dirname}/dist/`,
        filename: "server.bundle.js",
    },
    target: "node",
    node: {
        __filename: true,
        __dirname: true,
    },
    resolve: {
        extensions: [
            ".js",
            ".jsx",
        ],
        modules: [
            "client",
            "node_modules",
        ],
    },
    module: {
        loaders: [
            {
                test: /.(js|jsx)$/,
                exclude: /node_modules/,
                loader: "babel-loader",
                query: {
                    presets: [
                        "react",
                        "es2015",
                        "stage-0",
                    ],
                    plugins: [
                        [
                            "babel-plugin-webpack-loaders", {
                                config: "./webpack.config.babel.js",
                                verbose: false
                            }
                        ]
                    ]
                },
            }, {
                test: /.json$/,
                loader: "json-loader",
            }, {
                test: /.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    limit: 8192,
                    emit: false
                }
            }, {
                test: /.css$/,
                loader: "css-loader/locals"
            },
        ],
    },
    plugins: [
        new ExternalsPlugin({
            type: "commonjs",
            include: `${__dirname}/node_modules/`,
        }),
    ],
};

I have a JSX file where the .theHeader should be applied to:

import React from "react";

import Links from "./Links.jsx";
import profilePic from "../../img/brand/profilePic.jpg";

export default class Header extends React.Component {
    constructor() {
        super();
    }

    render() {
        return (
            <header className="theHeader">
                <img src={profilePic} alt="Professional Picture"/>
                <h5>{this.props.pageName}</h5>
                <Links/>
            </header>
        );
    }
}

When I run my application, there are no stylesheets that appear in the Dev console that have been loaded. When I inserted the line:

<link rel="stylesheet" type="text/css" href="/app.css"/>

into the <head> of the initially served page, I got the error in the Dev console:

Refused to apply style from ‘http://localhost:8000/app.css‘ because its MIME type (‘text/html’) is not a supported stylesheet MIME type, and strict MIME checking is enabled.

(N.B.: As in MERN, I only want to load in the stylesheet in this way in production)

If I used an ES6 import for the stylesheet and gave it a default alias (i.e. style), so my code would be:

<header className={style.theHeader}>
    ...
</header>

I get the error:

TypeError: Cannot read property 'theHeader' of undefined
    at Header.render (E:/Documents/Projects/website/client/js/components/Header.jsx:22:30)
    at resolve (E:DocumentsProjectswebsitenode_modulesreact-domcjsreact-dom-server.node.development.js:2149:18)
    at ReactDOMServerRenderer.render (E:DocumentsProjectswebsitenode_modulesreact-domcjsreact-dom-server.node.development.js:2260:22)
    at ReactDOMServerRenderer.read (E:DocumentsProjectswebsitenode_modulesreact-domcjsreact-dom-server.node.development.js:2234:19)
    at Object.renderToString (E:DocumentsProjectswebsitenode_modulesreact-domcjsreact-dom-server.node.development.js:2501:25)
    at E:/Documents/Projects/website/server/config/lib/express.js:204:31
    at Layer.handle [as handle_request] (E:DocumentsProjectswebsitenode_modulesexpresslibrouterlayer.js:95:5)
    at trim_prefix (E:DocumentsProjectswebsitenode_modulesexpresslibrouterindex.js:317:13)
    at E:DocumentsProjectswebsitenode_modulesexpresslibrouterindex.js:284:7
    at Function.process_params (E:DocumentsProjectswebsitenode_modulesexpresslibrouterindex.js:335:12)
    at next (E:DocumentsProjectswebsitenode_modulesexpresslibrouterindex.js:275:10)
    at p3p (E:DocumentsProjectswebsitenode_modulesluscalibp3p.js:15:9)
    at E:DocumentsProjectswebsitenode_modulesluscaindex.js:59:28
    at xframe (E:DocumentsProjectswebsitenode_modulesluscalibxframes.js:12:9)
    at E:DocumentsProjectswebsitenode_modulesluscaindex.js:59:28
    at xssProtection (E:DocumentsProjectswebsitenode_modulesluscalibxssprotection.js:16:9)

When running the application, webpack reports that the stylesheet has been loaded:

enter image description here

I am a novice to webpack but, from what I can see, webpack should not be playing a role here as I am running in development mode of which the ExtractTextPlugin should not play a role. Regardless, I included it anyway.

So the underlying issue is that, for some reason, using CommonJS’ require() to import the stylesheet in dev mode is not working.


Get this bounty!!!

#StackBounty: #javascript #jquery-update How to add touch to jQuery slider field?

Bounty: 50

I am on Drupal 7 using the sliderfield module (https://www.drupal.org/project/sliderfield)

I want the field to be mobile and touch friendly.

The module recommends using the Jquery UI Touch Punch module to solve this (https://www.drupal.org/project/jquery_touchpunch/issues/2797477) however it is not working.

Can anyone recommend an approach that will work with step by step examples?

An example could include adding code to a custom theme that can work without using the above referenced module.


Get this bounty!!!

#StackBounty: #javascript #reactjs #flowtype How can I spread props to a React component that uses exact props when using Flow?

Bounty: 100

Consider the following example using flow props.

import * as React from 'react';

type FooProps = {| 
  foo: number,
  bar?: string 
|};

class Foo extends React.Component<FooProps> {}

We have React component class Foo that accept an exact object of props. We want to enforce exactness so that users are not inadvertently making typos on their props (e.g. baz when they meant to use bar).

This works absolutely fine and errors happen as expected.

However, what if we want to spread props to this component from somewhere else? For example:

const f = (props: FooProps) => <Foo {...props} />;

Flow will give us an error about exactness on props:

10: const f = (props: FooProps) => <Foo {...props} />;
                                    ^ Cannot create `Foo` element because inexact props [1] is incompatible with exact `FooProps` [2].
References:
10: const f = (props: FooProps) => <Foo {...props} />;
                                   ^ [1]
8: class Foo extends React.Component<FooProps> {}
                                     ^ [2]

Disregarding the argument, “you shouldn’t spread props to components like that when you’re asking for exactness”, how can spreading be achieved?

I did find one way to do this, but it uses an undocumented utility type $Shape<T> (code). It’s unclear if this has any consequences or side effects, but it appears to work correctly:

class Foo extends React.Component<$Shape<FooProps>> {}

Here’s a link to try out what I’ve got using $Shape<T> with items I expect to error (and not):


Get this bounty!!!

#StackBounty: #javascript #google-maps #google-apps-script #async.js Bottlenecks in asynchronous JavaScript code for Google Map

Bounty: 50

I’m working on a pothole map web app in Google Apps Script. The map gets its data from a Google spreadsheet (from manual surveying), which is then transformed via hits to the Geolocation and Google Maps Roads APIs. There are 101 markers on the map (one marker per row of data, which represents either a pothole or a cluster of potholes). This map, for some odd reasons, takes about 20 seconds to load initially. Unacceptable!

This app makes use of the following APIs:

  • jQuery
  • Google Maps Roads
  • Google Geolocation
  • async.js
  • Mustache.js

I profiled my code , and from what it seems, most of the CPU time is from methods that don’t appear to be business ones. I analyzed the code profile two ways:

Self time

There were at least three heavy function calls in this respect, although nothing that seems to be too bad.
enter image description here

Total time

There was no business logic right at the top of this list, but plenty right below it. I present thus:
enter image description here

I then identify the lines of code where these bottlenecks appear:

addPotholeMarker()

/* Adds marker to map.
 * Parameters : 
 *  • potholeData  : a PotholeData (or PotholeDataFromCoords) object
 *  • snappedToRoad: boolean
 *  • callback     : the function to call next (optional)
 * Returns : 
 *  • the marker that was added to the map, or null if arguments invalid, or callback() if it was provided
 */
function addPotholeMarker(potholeData, snappedToRoad, callback) {
  // make sure that callback is either falsy or a function
  if ((callback) && (typeof callback !== 'function')) throw new TypeError('callback specified but not a function. Thrown from addPotholeMarker()'); 
  // make sure potholeState is either falsy or contains iconURL string
  if ((!potholeData.potholeState) || ((potholeData.potholeState) && (potholeData.potholeState.iconURL === undefined))) throw new Error('invalid potholeData');
  // let's make sure to snap this to road if it isn't already...  
  var coords = new GPSCoordinates(potholeData.lat, potholeData.lng);
  if (!snappedToRoad) 
  { 
    var potholeMarker = 'a garbage return value';
    getRoadCoordinates(coords).done(function(response) {
        var coords = response.snappedPoints[0].location;
        potholeData.lat = coords.latitude;
        potholeData.lng = coords.longitude;
        potholeData.isSnappedToRoad(true);
        return (potholeMarker = addPotholeMarker(potholeData, true, callback));
   /*     potholeMarker = addPotholeMarker(potholeData, true);
        return potholeMarker;*/
    });
    if (callback) return callback(null);
    return; 
    //return potholeMarker;
  }
  var marker = new google.maps.Marker({
    position: coords,
    title: coords.toString(),
    map: map,
    opacity: 0.5,
    icon: ((potholeData.potholeState.iconURL !== undefined) ? potholeData.potholeState.iconURL : PURPLE_MARKER)
  });

  // make marker have effect when mouseout,mouseover
  marker.addListener('mouseover', function(mouseEvent) {
    marker.setOpacity(1.0);
  });
  marker.addListener('mouseout', function(mouseEvent) {
    marker.setOpacity(0.5);

  });

  var infoWindow = createInfoWindow(potholeData);
  // save infoWindow for later reference
  infoWindows[statesMap.get(getPotholeStateFor(potholeData))].push(infoWindow);
  // on click of marker, show infoWindow
  marker.addListener('click', function(mouseEvent) { 
    infoWindow.open(map, marker);
  });
  // add this to potholeMarkers
  potholeMarkers[statesMap.get(getPotholeStateFor(potholeData))].push(marker);  
  if (callback) return callback(null, marker);
  return marker;
}

snapPotholeCoordsToRoad()

/* snaps potholes stored in potholeCoordinates to road
 * Parameters: 
 *  • potholeCollection : (Object<Array<PotholeData> >) the Collection of PotholeData to use
 *  • callback          : the function to call next
 */
// TODO: refactor the body of this so as to use potholeCollection (preferrably instead of potholeCoordinates)
function snapPotholeCoordsToRoad(potholeCollection, callback)
{
    var DEBUG = false;
    // guarantee that callback is function
    if ((callback) && (typeof(callback) !== 'function')) throw new TypeError('callback is something, but not a function. Thrown from snapPotholeCoordsToRoad().');
    // for each element of potholeCollection
    if (DEBUG) console.log('potholeCollection === ' + JSON.stringify(potholeCollection, null, 't'));
    var keys = [];
    for (var key in potholeCollection)
    {
        if (typeof potholeCollection[key] !== 'function') keys.push(key);
    }
    for (var key in potholeCollection)
    {
        (function itr(k, m) { 
            if (typeof potholeCollection[k] === 'function') return;
            if (m === potholeCollection[k].length) return;
            if (DEBUG) console.log('potholeCollection.' + k + '[' + m + '] == ' + JSON.stringify(potholeCollection[k][m], null, 't'));
            // if element (PotholeData) not snapped to road
            if (!potholeCollection[k][m].isSnappedToRoad())
            {
                // get road coordinates for element
                getRoadCoordinates(potholeCollection[k][m])
                // replace element's coordinates with those road coordinates
                .done(function(newCoords) { 
                    potholeCollection[k][m].setCoordinates(newCoords.snappedPoints[0].location);
                    //debugger;
                    potholeCollection[k][m].isSnappedToRoad(true);
                    if (DEBUG) console.log('potholeCollection.' + k + '[' + m + '] == ' + JSON.stringify(potholeCollection[k][m], null, 't'));
                    if ((k === keys[keys.length - 1]) && (m === potholeCollection[k].length - 1) && (callback)) return callback(null, null, potholeCollection);
                    itr(k, m+1);
                })
            }
            else
            {
                if ((k === keys[keys.length - 1]) && (m === potholeCollection[k].length - 1) && (callback)) return callback(null, null,  potholeCollection);
                itr(k, m+1);
            }
        })(key, 0);
    }
}

addPotholeMarkers()

/* put all potholes on the map 
 * Parameters:
 *  • callback         : the function to call next
 *  • unsnappedPotholes: (<Object<Array<PotholeData> > ) collection of potholes with coordinates that have not been snapped to road
 *  • snappedPotholes  : (<Object<Array<PotholeData> > ) collection of potholes with coordinates that are snapped to road
 */
function addPotholeMarkers(unsnappedPotholes, snappedPotholes, callback)
{
    var DEBUG = false;
    // guarantee that callback is function
    if ((callback) && (typeof(callback) !== 'function')) throw new TypeError('callback is something, but not a function. Thrown from addPotholeMarkers().');
    // add all the markers for them to the map
    async.waterfall([
        function(cb) { 
            async.eachOf(unsnappedPotholes, function(value, key) {
                // TODO: refactor this
                async.eachOf(value, function (v, k) { 
                    if (DEBUG) console.log('dealing with unsnappedPotholes');
                    //console.assert(v.potholeState.toString() != '[object Object]', 'toString() override missing');
                    //v = revivePotholeState(v); // unnecessary, because addPotholeMarker() invokes getPotholeStateFor() to force the potholeState to be in the statesMap
                    addPotholeMarker(v, false);
                })
            })
            cb(null);
        }, function(cb) {
            async.eachOf(snappedPotholes, function(value, key) { 
                async.eachSeries(value, function(pothole, fn) { 
                    if (DEBUG) console.log('pothole == ' + JSON.stringify(pothole, null, 't'));
                    addPotholeMarker(pothole, 
                        true,
                        //pothole.isSnappedToRoad(),
                        fn); 
                })
            })
            cb(null);
        }], function(err, results) {
            console.log('trying to center map');

            adjustMap();
            console.log('Map recentered');
            if (callback) { 
                callback(err);
            }
        });


}

The driver function

google.script.run.withSuccessHandler(function(data) { 
        async.waterfall([//fetchServerPotholeData,  // for some reason, this function is not receiving data
            function(callback) { 
                fetchServerPotholeData(data, callback);
            },
            fetchCoords,
            snapPotholeCoordsToRoad,
            addPotholeMarkers
            ], function(err, result) { 
                if (!err) { 
                    console.log('Everything successfully done. Enjoy your map!'); 

            }
            else 
            {
                console.error(err);
            }
        }
    )
}).withFailureHandler(console.log).getPotholeData();

I’m trying to fix these bottlenecks but am not sure how.

UPDATE

I’m adding a link to the GitHub project itself that I created the other day, since this question’s been crickets since I asked it.


Get this bounty!!!

#StackBounty: #javascript #reactjs #typescript #autocomplete #draftjs Implement Autocomplete in Draft JS but without a "trigger&qu…

Bounty: 300

I want to implement something like a tag editor. However, it’s meant just for those tags so I want the user to see the autocomplete suggestions popup without having to type something like @ or #, just the text itself.

I have something that kinda works, but the popup displays in strange positions on the screen:

  • when I first type something and the popup appears, it appears somewhere near the top-left corner of the screen
  • after the first entity is created, when press SPACE and start typing again, the popup appears a couple of pixels to the right from it’s intuitive position (i.e. under the first letter of the word)

Here is an example of a well-known editor of this kind (although not implemented with Draft), so you can get a better understanding of what I want to implement.

Gmail email composer

First things first, here is the function that triggers the suggestions popup:

private onChange(editorState: EditorState) {
  const content = editorState.getCurrentContent();
  const selection = editorState.getSelection();
  const currentBlock = content.getBlockForKey(selection.getAnchorKey());

  if (selection.isCollapsed()) {
    const blockText = currentBlock.getText();
    const wordMeta = getWordAt(blockText, selection.getAnchorOffset());
    const categoryRegex = /([w]*)/;
    const matches = wordMeta.word.match(categoryRegex);
    const existingEntity = currentBlock.getEntityAt(wordMeta.begin);

    if (!existingEntity && matches) {
      const categorySearch = matches[1];
      const selection = window.getSelection();
      if (this.state.autoComplete.search !== categorySearch && selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const boundingRect = getRangeBoundingClientRect(range);

        this.setState((prevState: StateType) => {
          let state = {
            autoComplete: {
              active: true,
              search: categorySearch,
              searchMeta: {
                begin: wordMeta.begin,
                end: wordMeta.end,
              },
            },
            selectionRect: prevState.selectionRect,
          };

          if (prevState.autoComplete.active === false) {
            state.selectionRect = boundingRect;
          }

          return state;
        });
      }
    }
  }

  this.props.onChange(editorState);
}

Here is the getWordAt function:

function getWordAt(text: string, pos: number): WordMeta
{
  const left = text.slice(0, pos + 1).search(/S+$/);
  const right = text.slice(pos).search(/s/);

  if (right < 0) {
    return {
      word: text.slice(left),
      begin: left,
      end: text.length,
    };
  }

  return {
    word: text.slice(left, right + pos),
    begin: left,
    end: right + pos,
  };
}

What would be a better way of handling the position of the popup and maybe even the strategy for autocompletion of this kind as well? Thank you!


Get this bounty!!!

#StackBounty: #javascript #vue.js JS, Vue: how to split text based on window height?

Bounty: 50

I have text that I want to split at a specific point so that you dont need to scroll down.

That means I want to know when the text gets longer than the availible height of the window. This needs to be known before I show the text. The problem with that is that I need to know how my layout will look like before I render it, because the whole thing should be responsive to width and height.

I also plan to resize the fontsizes a little. So taking all that to account, does anyone of you know of you know how to split the text at the correct point?

Thank you in advance^^.

PS: The text is actually an array and is looking like this for e.g.:

text = [{content: Hello, wordID: ..., offsetBegin: 0, offsetEnd: 5, ...},{content: World!, wordID: ..., offsetBeding: 7, offsetEnd: 12,...}]

So the only thing I need to know is the indexes on where to split the text so that there are no scrolbars on the main window. Splitting the text can occur more than once too.

The whole thing will start to be displayed and computed in the mounted() hook and will be recomputed each time the ‘resize’ event of for window is fired.


Get this bounty!!!

#StackBounty: #javascript #node.js #asynchronous Reducing Repetitive Handlers in an Asynchronous Environment

Bounty: 50

I am currently working on a Node.js Socket Server for my messaging service and have been thinking about a way to re-organize my code to make it more understable, flow better, and most importantly—be manageable. In order to give an idea about what I think is wrong with the structure, I will present a trimmed version:

'use strict';

let SocketServer = require('./InitializeServer.js'); // server initialization
const MessageSender = require('./Messaging.class.js'); // import the Messanger Class
const Database = require('./SQL.js');

const conn = Database.Connection;
const SQL = Database.SQL;

/** This method is in another file and establishes a secure websocket server
 *
 *  @param {ClientObject} An object that describes everything about the client
 *  @param {ConnectionObject} An object that describes everything about the currection connection of a user, note ConnectionObject depends on ClientObject
 *  @param {req} Connection request param
 */
SocketServer.runWebSocketServer(function (ClientObject, ConnectionObject, req) {
    let poll = null;
    let _self = ClientObject.get();

    const Messanger = new MessageSender(ClientObject);
    const Chat = new SocketServer.EventDispatcher(ClientObject, ConnectionObject, {
        // these events require a "verify" key
        verify: ['status', 'actions']
    });

    // all of my handlers go here

    Chat.on('message', function (data) {
        // send out messages
    }, true);

    Chat.on('status', function (data, subtype, applyToAll) {
        // send out status messages
    }, false);

    Chat.on('typing', function (data) { 
        // "is typing" mechanism
    }, true);

    Chat.on('actions', function (action, type) {
        // set actions
    }, true);

    Chat.on('loadMore', function (start) {
        // do something here
    }, true);

    Chat.on('close', function close() {
        console.log("CLOSE CONNECTION");
    });

    // do a few more general operations below
});

Being that I am quite new to the Node.js environment, the repetitive section of the code throws up some flags. Extendability is typically hindered by such repetitive behavior. As a consideration, I could change the lines that repeat to follow a more object oriented approach*:

    Chat.on(new MessageEvent());
    Chat.on(new StatusEvent());
    Chat.on(new TypingEvent());
    Chat.on(new Actions());
    Chat.on(new LoadingEvent());
    Chat.on(new CloseEvent());

I am unsure if this would be the correct or best practice. What do you think?

*Note that the .on method does not come from any native implementation so I am very flexible


Get this bounty!!!

#StackBounty: #javascript #base64 ie11 Downloading Base64 documents

Bounty: 100

I have tried pretty much everything at this point and I cannot get anything to work in ie.

I need ie to download base64 documents from an attachment panel. I have no access to the server side code or database. The images cannot be stored in a folder to be pulled up, they need to be presented this way.

I have tried using a plain link and sticking the base64 sting in there and it just opens up a new blank window.

<a target="_blank" download class="btn btn-primary downloadAttachment" href="' + blobUrl + '" >Download</a>

I have tried turning the url into a blob and opening the blob and that resulted in the browser not doing anything.

function base64toBlob(base64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = base64Data;
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

I am completely and totally stuck. I have tried everything from google and on here.

My two latest attempts here

https://jsfiddle.net/pqhdce2L/

http://jsfiddle.net/VB59f/464/


Get this bounty!!!

#StackBounty: #javascript #html #geolocation Adding multiple listeners to navigator.geolocation.getCurrentPosition

Bounty: 50

I am adding three listeners for location updates.

<!DOCTYPE html>
    <html>
    <body>
    
    <p>Click the button to get your coordinates.</p>
    
    <button onclick="getLocation()">Try It</button>
    
    <p id="demo1"></p>
    <p id="demo2"></p>
    <p id="demo3"></p>
    
    
    var x = document.getElementById("demo1");
    var y = document.getElementById("demo2");
    var z = document.getElementById("demo3");
    
    function getLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(showPosition1);
            navigator.geolocation.getCurrentPosition(showPosition2);
            navigator.geolocation.getCurrentPosition(showPosition3);
        } else { 
            x.innerHTML = "Geolocation is not supported by this browser.";
        }
    }
    
    function showPosition1(position) {
        alert("showPosition1");
        x.innerHTML = "Latitude: " + position.coords.latitude +  "
Longitude: " + position.coords.longitude; } function showPosition2(position) { alert("showPosition2"); y.innerHTML = "Latitude: " + position.coords.latitude + "
Longitude: " + position.coords.longitude; } function showPosition3(position) { alert("showPosition3"); z.innerHTML = "Latitude: " + position.coords.latitude + "
Longitude: " + position.coords.longitude; } </body> </html>

In case of Safari and Chrome, all three methods are called. While in case of Firefox, only the last listener method is called.

So what is the default implementation for the location detection feature. Is there a work around to ensure that all the callback methods are called on Firefox.


Get this bounty!!!

#StackBounty: #javascript #oop #prototype #base-class #extending Javascript prototype extend base-class unable to access base-class pro…

Bounty: 50

I have created a javascript class TkpSlider being inspired from this w3schools page. (JSFiddle)

var TkpSlider = function (args) {
    args= args|| {};
};

var mainSwiper = new TkpSlider();

I have extended this to add some swipe ability being inspired from this page so that I can the slider works on user swipe. (JSFiddle)

var TkpSwiper = function (args) {
    TkpSlider.call(this, args);
};

TkpSwiper.prototype = Object.create(TkpSlider.prototype);

var mainSwiper = new TkpSwiper();

I separated the code so I don’t get confused later from the base code and if any additional function. But with OOP I have to extend by creating a new name for it TkpSwiper, But I want to find another way to use the same name TkpSlider.

I saw this article and tried to use prototype to extend TkpSlider in this JSFiddle (Snippet below). The problem is I can’t access the public methods of the base class from child class. The sample javascript in the blog I tested working though, I must be missing something with my code. Could anyone shed some insight? Thanks.

<

div class=”snippet”>

var TkpSlider = function (args) {
    args= args|| {};
    //private variable
     var btnPrev = args.btnPrev || "tkp-slide-btn-prev";//class for previous button (default: "tkp-slide-btn-prev")
    var btnNext = args.btnNext || "tkp-slide-btn-next";//class for next button (default: "tkp-slide-btn-next")
    var itemClass = args.itemClass || "tkp-slide-item"; //each item container class to slide (default: "tkp-slide-item")
    var isAutoSlide = args.isAutoSlide || false;//set auto slide (default: false)
    var autoSlideTimer = args.autoSlideTimer || 2000;//set auto slide timer when isAutoSlide is true(default: 2000)
    var hideBtnNav = args.hideBtnNav || false; //hide button navigation(default: false)
    var isRandom = args.isRandom || false; //whether next or previous slide should be random index
    var slideIndex = args.startIndex || 0; //start slide index number (zero based, index 0 = slide number 1, default :0)


    var itemNodes = document.getElementsByClassName(itemClass);
    var itemLength = itemNodes.length;
    var autoSlideInterval;

    //public variable
    this.testParentVar = "parent var";

    //init function
    init();
    function init() {
        if (itemLength > 0) {
            showSlide();
            bindEvent();
            isAutoSlide ? setAutoSlide() : "";
            hideBtnNav ? setHideBtnNav() : "";
        } else {
            throw "Cannot find slider item class";
        }

    }


    //private function
    function showSlide() {
        if (slideIndex >= itemLength) { slideIndex = 0; }
        if (slideIndex < 0) { slideIndex = (itemLength - 1); }
        for (var i = 0; i < itemLength; i++) {
            itemNodes[i].style.display = "none";
        }
        itemNodes[slideIndex].style.display = "block";
    }

    function nextPrevSlide(n) {
        slideIndex += n;
        showSlide();
    }

    function bindEvent() {
        var btnPrevNode = document.getElementsByClassName(btnPrev);
        if (btnPrevNode.length > 0) {
            btnPrevNode[0].addEventListener("click", function () {

                if (isRandom) {
                    setRandomSlideIndex();
                } else {
                    nextPrevSlide(-1);
                }


                if (isAutoSlide) {
                    clearInterval(autoSlideInterval);
                    setAutoSlide();
                }
            });
        } else {
            throw "Cannot find button previous navigation";
        }

        var btnNextNode = document.getElementsByClassName(btnNext);
        if (btnNextNode.length > 0) {
            btnNextNode[0].addEventListener("click", function () {
                if (isRandom) {
                    setRandomSlideIndex();
                } else {
                    nextPrevSlide(1);
                }
                if (isAutoSlide) {
                    clearInterval(autoSlideInterval);
                    setAutoSlide();
                }
            });
        } else {
            throw "Cannot find button next navigation";
        }

    }

    function setAutoSlide() {
        autoSlideInterval = setInterval(function () {
            if (isRandom) {
                setRandomSlideIndex();
            } else {
                nextPrevSlide(1);
            }

        }, autoSlideTimer);
    }

    function setHideBtnNav() {
        document.getElementsByClassName(btnPrev)[0].style.display = "none";
        document.getElementsByClassName(btnNext)[0].style.display = "none";
    }

    function setRandomSlideIndex() {
        var randomIndex = Math.floor(Math.random() * itemLength);
        if (randomIndex == slideIndex) {
            setRandomSlideIndex();
        } else {
            slideIndex = randomIndex;
            showSlide();
        }
    }

    //public function
    this.nextPrevSlide = function (n) {
        nextPrevSlide(n);
        //console.log("nextPrevSlide");
    };

    //getter setter
    this.setItemClass = function (prm) {
        itemClass = prm;
    };
    this.getItemClass = function () {
        return itemClass;
    };


};

//Adding touch swiper
TkpSlider.prototype = function () {
    var self = this;
    var touchStartCoords = { 'x': -1, 'y': -1 }, // X and Y coordinates on mousedown or touchstart events.
        touchEndCoords = { 'x': -1, 'y': -1 },// X and Y coordinates on mouseup or touchend events.
        direction = 'undefined',// Swipe direction
        minDistanceXAxis = 30,// Min distance on mousemove or touchmove on the X axis
        maxDistanceYAxis = 30,// Max distance on mousemove or touchmove on the Y axis
        maxAllowedTime = 1000,// Max allowed time between swipeStart and swipeEnd
        startTime = 0,// Time on swipeStart
        elapsedTime = 0,// Elapsed time between swipeStart and swipeEnd
        //targetElement = document.getElementById('el'), // Element to delegate
        targetElements = self.getItemClass()
        ;

    init();
    function init() {
       
        addMultipleListeners(targetElements, 'mousedown touchstart', swipeStart);
        addMultipleListeners(targetElements, 'mousemove touchmove', swipeMove);
        addMultipleListeners(targetElements, 'mouseup touchend', swipeEnd);
    }

    function swipeStart(e) {
        e = e ? e : window.event;
        e = ('changedTouches' in e) ? e.changedTouches[0] : e;
        touchStartCoords = { 'x': e.pageX, 'y': e.pageY };
        startTime = new Date().getTime();
        //targetElement.textContent = " ";
    }

    function swipeMove(e) {
        e = e ? e : window.event;
        e.preventDefault();
    }

    function swipeEnd(e) {
        e = e ? e : window.event;
        e = ('changedTouches' in e) ? e.changedTouches[0] : e;
        touchEndCoords = { 'x': e.pageX - touchStartCoords.x, 'y': e.pageY - touchStartCoords.y };
        elapsedTime = new Date().getTime() - startTime;
        if (elapsedTime <= maxAllowedTime) {
            if (Math.abs(touchEndCoords.x) >= minDistanceXAxis && Math.abs(touchEndCoords.y) <= maxDistanceYAxis) {
                direction = (touchEndCoords.x < 0) ? 'left' : 'right';
                switch (direction) {
                    case 'left':
                        //targetElement.textContent = "Left swipe detected";
                        console.log("swipe left");
                        self.nextPrevSlide(1);

                        break;
                    case 'right':
                        // targetElement.textContent = "Right swipe detected";
                        console.log("swipe right");
                        self.nextPrevSlide(-1);

                        break;
                }
            }
        }
    }

    function addMultipleListeners(el, s, fn) {
        var evts = s.split(' ');
        var elLength = el.length;
        for (var i = 0, iLen = evts.length; i < iLen; i++) {
            if (elLength > 1) {
                for (var j = 0; j < elLength; j++) {
                    el[j].addEventListener(evts[i], fn, false);
                }
            } else {
                el.addEventListener(evts[i], fn, false);
            }

        }
    }
}();

var mainSwiper = new TkpSlider();
.tkp-slide {
  width: 100%;
  position: relative; }
  .tkp-slide .tkp-slide-item:not(:first-child) {
    display: none; }
    .tkp-slide .tkp-slide-item img {
      width: 100%; }
  .tkp-slide .tkp-slide-btn {
    color: #fff !important;
    background-color: #000 !important;
    border: none;
    display: inline-block;
    outline: 0;
    padding: 8px 16px;
    vertical-align: middle;
    overflow: hidden;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    white-space: nowrap;
    opacity: 0.7; }
    .tkp-slide .tkp-slide-btn:hover {
      background-color: #333 !important; }
  .tkp-slide .tkp-slide-btn-prev {
    position: absolute;
    top: 50%;
    left: 0%;
    transform: translate(0%, -50%);
    -webkit-transform: translate(0%, -50%);
    -ms-transform: translate(0%, -50%); }
    .tkp-slide .tkp-slide-btn-next {
      position: absolute;
      top: 50%;
      right: 0%;
      transform: translate(0%, -50%);
      -ms-transform: translate(0%, -50%); }
<section class="main-slide">
  
<ul> <li class="tkp-slide-btn tkp-slide-btn-prev"> ❮ </li> <li class="tkp-slide-btn tkp-slide-btn-next"> ❯ </li> </ul> </div> </section>


Get this bounty!!!