Making a Native ELM module with Moment.js - javascript

I've been playing around with Elm for a couple of days and I wanted to make a port of Moment.JS, since I've seen a lack of libraries for what I wanted, and Moment just has everything that I need.
The thing is that I always face the same error. I have Moment.JS in my Native folder (it is named MomentJS.js) and another file called Moment.js (my wrapper). The problem is that when I call moment in Moment.js, I get an error saying that moment is not defined.
I've tried to import MomentJS.js in my elm file as well, before and/or after Moment.js. I've also tried to copy the whole JS into Moment.js and add my wrapper at the end of it. None of this things worked. You know what could I do? I've been looking for similar repos on the internet but I've never seen a module that has a wrapper and another JS file just for the native library.
This is my Moment.js code:
var _user$project$Native_Moment = (function() {
var moment = require('moment');
var format = function ( format, date ) {
return moment().format();
}
return {
format: format
};
})();
and my Moment.elm code:
module Moment exposing (format)
{-| A module desc
#docs format
-}
import Native.MomentJS
import Native.Moment
{-| Call the default `Moment.js` format method
-}
format : String -> String -> String
format fm dt = Native.Moment.format fm dt
The last thing that I tried was to download Moment from npm, copy its folder from the node_modules folder to my Native folder and do moment = require('moment') but I got TypeError: fun(...) is not a function.
Any suggestions?

After some digging, what you are looking to do is completely possible yes! :) However, it won't be a simple copy paste. Look at the source you posted here, it will require mapping every function to the native elm functions, i'd recommend starting small with this conversion.
First, Get a simple hello world Native example work, see here
Secondly, add in some of the simpler functions from moment.js one by one, i'd recommend starting with moment\src\lib\format\format.js
Lastly, I know this isn't what you want to hear, but if you really want to write javascript in elm, maybe Elm isn't what you are looking for? I really can't imagine converting an entire library similar to Moment.js would be simpler than creating your own Elm library inspired by Moment.js
Either way, best of luck! Seems like a fun challenge either way :)

There are two supported ways for Elm and JavaScript to talk to each other: ports and flags. Both are asynchronous and will be awkward for your needs.
https://guide.elm-lang.org/interop/javascript.html
Should you write native code? Elm's creator says no.
So the best path forward is to use one of the existing time/date libraries or write what you need yourself.

Related

Is moment.js and moment.php the same?

I have created a js script using moment.js and I want to replicate it through a cron job. So, it will be in PHP.
So, I searched for moment.js equivalents and I found this https://github.com/fightbulc/moment.php
Technically speaking, they are not the same. The GitHub repo says:
Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js
I read "inspired by" as similar in nature or close to. Otherwise, it would say something like "PHP port of Moment.js" or "PHP wrapper around Moment.js".
You should define more clearly, however, what exactly you mean by "are they the same". Do you mean the API parity? Or API compatibility? Or something else?
Well, it's not the same as it says "Inspired by the javascript library moment.js" at below mentioned sources :
1) https://packagist.org/packages/lawondyss/moment-php
2) https://github.com/fightbulc/moment.php
which means it is developed by taking the reference of the javascript library moment.js , it may contain the same functionality as well as it's own (newly added than the javascript moment.js).
You can compare the two from downloading/checking the documentation from different sources as below :
1) for moment.js you can check here : https://momentjs.com/
2) for moment.php you can check here : https://github.com/fightbulc/moment.php OR
https://packagist.org/packages/lawondyss/moment-php

javascript, import array from js file

I am trying to import array from js file to another js file. link For example:
file1.js:
var array = ['one', 'two', 'three'];
file2.js:
import { array } from 'file1'
My idle says that "import declaration are not supported by current Javascript version." How can I import this array?
Thank You for any help
As mentioned by article you linked, import is available with ES6.
I think you're writing ES5 JavaScript, then you'll need a ES6 transpiler such as Babel.
https://codeburst.io/es5-vs-es6-with-example-code-9901fa0136fc
importing is only allowed in ES6, the newest version of javascript so to speak. Browsers are just now getting around to being able to "understand" ES6, and they won't be able to understand it completely for awhile. Currently, browsers understand the previous version of javascript, ES5, really well. So how can you write code that uses import since it's ES6?
Unfortunately, you need some special tools that change code that you write in ES6 to ES5 so that browsers can understand your code. This is called transpiling. A tool called Babel is by far the most popular transpiler used today. But that's not all. You'll need another tool to bundle the modules you write in ES6 syntax. Rollupjs and Webpack are the most popular tools for this task.
It can take a few weeks of reading and trying things out to learn these tools, so unfortunately I can't explain them well enough in one answer here for you to get a complete understanding. Basically what bundling does, using your example: file1.js and file2.js will be combined into one single final file bundle.js and this is the file that you will include <script src="bundle.js"> in your html. file2.js is called a module. How does this new help write better code? Well we can write most of our code in modules and then just import whatever modules I need on particuler pages. If I need a countdown timer on page1.html, I'll create a module which has the code needed for a countdown timer, and import the countdown timer module. If I need a countdown timer on a new page 6 months from now, I will just import the countdown timer module on this new page. Code reusability.
Webpack is more popular than Rollup, but I would recommend using Rollup to get a good overview of what a bundler actually does. We use Rollup in our enterprise application in fact, although Webpack is more widely used I think, as it does many many things beyond bundling.
Note: ES6 is not really the newest version of javascript; we already have ES7 and ES8 coming along. In fact, there are new features constantly being added to the official javascript language. The problem is that it takes time for browsers to implement (be able to "understand") these new features.
The best way I can think to replicate the behavior in ES5 is to create an iframe with a script tag to the file you want. Onload you can grab the desired variable and bring it into the parent window. Then destroy the iframe.
Usage would be something like this:
import('file-url', 'variable-name', function(imported){
});
Implementation would be something like this:
function import(filePath, varName, callback){
//create iframe
//create script tag
//add filepath and onload handler
script.onload = function(){
//retrieve variable and
//trigger callback in parent
};
}

Date formatting and manipulation in PebbleJS

I'm writing an app using PebbleJS in CloudPebble and would like to have functionality similar to that provided by Moment.js and xdate.js. Specifically, I am interested in:
turning a datetime into a string using a custom format string
adding and subtracting days/weeks/months/years from the current datetime
These modules claim to support CommonJS, so I've tried adding the files to CloudPebble and importing with something like var Moment = require('moment');. When I do this, the app will simply fail to run. I'm not even sure that it compiles.
All I can find in the logs is:
[PHONE] pebble-app.js:?: [PHONESIM] [WARNING] Exception decoding QemuInboundPacket.footer
I see here that moment.js is included in the vendor folder of Pebble.JS. The reasoning for that error must be something universal as I am getting the same error when I try the same thing on a HelloWorld brand new Pebble.JS project on CloudPebble.
I looked at the source code from a pbw export from cloudpebble and it has the full library inside the file. It seems that part of the clock.js file uses moment.js
Look here on how to reference the clock library and inherit the moment.js library at the same time.

Unminify / Decompress JavaScript

Original Question
This maybe a stupid question but is there a way in VS 2013 to unminify JavaScript?
Just making sure we are all on the same page here.
Minify:
var flashVer=-1;if(navigator.plugins!=null&&navigator.plugins.length>0){if(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]){var swVer2=navigator.plugins["Shockwave Flash 2.0"]?"
That's just an example to make sure we all know what I'm on about. As far as I can tell there is no way to be able to do this. I have only been using VS 2013 for around 3 weeks so there is probably still stuff that is hidden to me.
If there is no way to do this within the program what is the next best thing for this?
I did see on another similar post that recommends the site http://jsbeautifier.org/ , so may have to give that ago but would make life easier if it was built into VS 2013
Thanks in advance as I know someone will be able to help me out here.
Update:
I have looked around VS 2013 and found nothing that can help me with this problem, like I said before they maybe some things I have missed (certain settings) so I guess if it cannot be done in VS what's the next best thing for the job? I seem to run into a fair amount of JS that is minifed and would like the quickest and best way to get the job done. I couple sites I have tried seem to have problems with it, is there a program I could install that would just allow me to short cut it with a hot-key or something. That would be pretty handy.
Update 2:
So I think its safe to say this cannot be done within VS2013, or for that matter at all due to missing var names and so on. So I have seen a few links and programs that allow you to format the code. Is there a way to do with within VS2013? And again if not what is the most reliable website/program that I can use to do this. Like I said I can see there have been answers and I appreciate all of them. I will be leaving this question open for a while to get more people to look at it and possibly give a better answer. Keep it up guys!
Update 3:
If anyone has any more information on this please do share. I am still looking around now and then waiting for someone to come up with something amazing for this. One day people.... One day!
The thing is that you cannot really "unminify" your code since some data was already lost - e.g. variable names. You can reformat it to more readable form though.
According to this question, since VisualStudio 2012 you can just use Ctrl+E, D keyboard shortcut
If the above is not right, there is this extension for VS 2010: http://visualstudiogallery.msdn.microsoft.com/41a0cc2f-eefd-4342-9fa9-3626855ca22a but I am not sure if it works with VS 2013
There is an extension to VisualStudio called ReSharper which can reformat javascript in a few different manners.
Also there are online formatters already mentioned in other answers (if your code is confidential, I would advise some paranoia manifested by downloading sources and using them locally).
Also you may always try to find unminified version of desired library on the interwebs
Also, there is the WebStorm IDE from JetBrains that is able to reformat JS - you may download a trial for the sole purpose of reformatting your minified scripts :)
If that's just to make debugging easier, you may want to use source maps
Also, here is a bunch of related questions:
How to automatically indent source code? <-- this is for VS2010, but it looks promising, maybe it will help you if it supports JavaScript (and it does since VS2012 according to MS support):
Ctrl+E, D - Format whole doc
Ctrl+K, Ctrl+F - Format selection
reindent(reformat) minimized jquery/javascript file in visual studio
Visual Studio 2010 can't format complex JavaScript documents
Visual Studio code formatter
how to make visual studio javascript formatting work?
I am not sure if they figured out a working way to reformat JS, but I've seen a few answers which might be helpful - I am just pasting this in here just FYI.
Added 03.06.2014:
http://www.jsnice.org/
This tool could be useful too, it even tries to infer minified names. As stated on their website:
We will rename variables and parameters to names that we learn from thousands of open source projects.
Personally I can't think of a reason to ever unminify code^:
If you're using a compiled js file (a-la google closure) and want more readable code to debug, use source maps available for well-supported libraries (speaking of jQuery, if it is served from a google CDN it already maps to the correct source)
If you're using a whitespace-only minified js file and want more readable code to debug, you could just toggle pretty print in-browser. This seems to best fit your question.
If you're using either of the above and want to modify the source code for a third-party js file, don't. Any future release will cancel out your change - instead consider one of the many patterns to extend a framework (or, perhaps, do some duck punching depending on the exact scenario.)
The other answers seem to cover the "unminification" process (maxification?) well, but it's worth making sure it's a necessary step first.
^ - Except when version control falls over, there are no backups and the only version of the file left is a minified copy in browser cache. Don't ask.
Its just a one way transformation .... sorry in normal cases you will not get something understandable back from minified JavaScript !
Make just a quick look at JQuery source for a second:
(function( window, undefined ) {
// Can't do this because several apps including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//"use strict";
var
// The deferred used on DOM ready
readyList,
// A central reference to the root jQuery(document)
rootjQuery,
// Support: IE<10
// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
core_strundefined = typeof undefined,
// Use the correct document accordingly with window argument (sandbox)
location = window.location,
document = window.document,
docElem = document.documentElement,
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// [[Class]] -> type pairs
class2type = {},
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
core_version = "1.10.2",
------
And now at the minify source:
(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,
l=e.jQuery,u=e.$,c={},p=[],f="1.10.2", ....
I think now you see it =>
window => e
undefined => t
readyList => n
rootjQuery => r
core_strundefined => i
location => o
document => a
So its mapped somehow to make it more shorter look here to minify something
People normally use this so there is no way back
you can just format it look here
If the code has only been minified then the best you can do automatically is reformat to make it more readable. One way of doing this is using an online formatter/beautifier. E.g. Copy and paste the line of code you posted into http://jsbeautifier.org/ or http://www.jspretty.com/ and it'll produce something like this:
var flashVer = -1;
if (navigator.plugins != null && navigator.plugins.length > 0) {
if (navigator.plugins["Shockwave Flash 2.0"]
|| navigator.plugins["Shockwave Flash"]) {
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? ""
But of course what these don't do is put any comments that have been removed by the minifier back in. And if the code has also been obfuscated then it will be a lot less readable since the variable names will have changed (e.g. var a instead of var flashVer). See here for further details.
As you can see from the other answers, there is no way to reconstitute minified Javascript back into its original form, it is a lossy compression. The best you can do is make it readable by reformatting it.
If the code is open source, then it is likely that the code will exists in a raw state on some form of version control site or as a zip. Why not just download the raw version if available?
There is an online tool to unminify Javascripts
http://jsbeautifier.org/
And also for CSS
http://mrcoles.com/blog/css-unminify/

libphonenumber standalone (without masses of google dependencies)? Alternate lib?

I am looking at using http://code.google.com/p/libphonenumber/ for a well-established project. Today the project does not use Google's libraries for JavaScript, favoring jQuery, jQueryUI, requirejs, and so on.
libphonenumber looks awesome ... except that the javascript version (svn co http://libphonenumber.googlecode.com/svn/trunk/javascript/ libphonenumber-js) is laced with goog.require calls. If one runs the demo (libphonenumber-js/i18n/phonenumbers/demo.html if you checked out as suggested) it pulls in tons of google libraries from closure-library.googlecode.com :
GET base.js
GET deps.js
GET error.js
GET string.js
GET asserts.js
GET array.js
GET useragent.js
GET browserfeature.js
GET tagname.js
GET classes.js
GET math.js
GET coordinate.js
GET size.js
GET object.js
GET dom.js
GET json.js
GET util.js
GET descriptor.js
GET fielddescriptor.js
GET message.js
GET serializer.js
GET objectserializer.js
GET stringbuffer.js
GET lazydeserializer.js
GET pbliteserializer.js
I believe if I compile this using the closure compiler ("If you give the use_closure_library parameter a value of true, the compiler looks for goog.require() statements in the source code and supplies the Closure Library code requested by any such statements.", https://developers.google.com/closure/compiler/docs/api-ref) I can cut down the raw number of requests, but this still seems like a rather excessive amount of content for a phone number parser, even a full-featured one.
My question has two possible answers:
A way to use libphonenumber in JavaScript without having to pull in all the Google JavaScript base libraries
An alternate standalone (as in doesn't have dozens of dependencies) first-class phone number processing library with both JavaScript and Java implementations
Any and all suggestions most appreciated.
I've got a custom build (currently 220KB) that I use for my International Telephone Input plugin, with plenty of helper functions exposed. Read the source for details.
You can also use my lib.
https://github.com/Gilshallem/phoneparser
Its only got one method but you can do a lot with it
parsePhone("12025550104");
result: { countryCode:1, areaCode:202, number:5550104, countryISOCode:"US" }
Here are two implementations of Google libphonenumber in JavaScript that have zero dependencies and are implemented in a single file. I've used Nathan Hammond's version without issue but it is not on NPM. Rui Marinho's version is on NPM.
https://github.com/nathanhammond/libphonenumber
https://github.com/ruimarinho/google-libphonenumber
I just spent 2 days figuring this out. For now, anyway, you can download a minified version of libphonenumber-js from here
drop it in place, with the usual
<script type="text/javascript" language="javascript" src="/static/js/libphonenumber-js.min.js"></script>
and get busy coding!
<script>
$(".phone-format").keyup(function () {
var val_old = $(this).val();
var newString = new libphonenumber.AsYouType('US').input(val_old);
$(this).focus().val('').val(newString);
});
</script>

Categories