Using sourceURL and sourceMappingURL with relative paths - google-chrome-devtools

It appears that sourceURL is made relative differently in Firefox and Chrome - when some tooling generates //# sourceURL=... strings in JS files that are relative to the file they are placed in, Firefox treats the URL as relative to the JS file, while Chrome instead treats it as relative to the original HTML file. Which is correct, or is there a clearer way to state this?
In this sample application, I'm trying to use sourceURL to allow many, smaller files to be combined into a single large file but still allow the browser to know what the smaller file should be called, and sourceMappingURL to then specify the sourcemap file, relative to that original file.
Directory structure:
index.html
js/
all.js
uncompiled/
app.js
app.js.map
app.min.js
The index.html is a minimal page to load either js/all.js or js/uncompiled/app.min.js. There is no other JS being baked into js/all.js (as this is a minimal example), but in theory there could be many here. The purpose of this file is just to combined the various minified JS files into one larger file, yet still allow the developer to see the original code, and set breakpoints accordingly.
Contents of app.js:
class App {
constructor(name) {
this.name = name;
}
sayHi() {
window.alert("Hello " + this.name);
}
}
new App("Colin").sayHi();
Then, running a simple minifier rebuilds that into app.min.js with a matching app.js.map file:
var App=function(a){this.name=a};App.prototype.sayHi=function(){window.alert("Hello "+this.name)};(new App("Colin")).sayHi();
//# sourceMappingURL=app.js.map
{
"version":3,
"file":"./app.min.js",
"lineCount":1,
"mappings":"AAAA,IAAMA,IAELC,QAAW,CAACC,CAAD,CAAO,CACjB,IAAAA,KAAA,CAAYA,CADK,CAIlB,IAAA,UAAA,MAAAC,CAAAA,QAAK,EAAG,CACPC,MAAAC,MAAA,CAAa,QAAb,CAAwB,IAAAH,KAAxB,CADO,CAKTC,EAAA,IAAIH,GAAJ,CAAQ,OAAR,CAAAG,OAAA;",
"sources":["app.js"],
"names":["App","constructor","name","sayHi","window","alert"]
}
And finally, that minified output is wrapped in eval, and the sourceURL param is added to the end (line breaks added for readability):
eval('var App=function(a){this.name=a};App.prototype.sayHi=function
(){window.alert("Hello "+this.name)};(new App("Colin")).sayHi();\n
//# sourceMappingURL=app.js.map\n//# sourceURL=uncompiled/app.min.js');
If the index.html directly points to js/uncompiled/app.min.js, then both Firefox and Chrome correctly understand that app.js.map is in the same directory, and should be used when debugging. However, if index.html points instead to js/all.js, then while both browsers correctly show the eval'd contents in an individual file, only Firefox makes the path relative to all.js.
Using python -m http.server on this structure shows these results in firefox:
127.0.0.1 - - [14/Jun/2019 08:33:37] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2019 08:33:37] "GET /js/all.js HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2019 08:33:38] code 404, message File not found
127.0.0.1 - - [14/Jun/2019 08:33:38] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [14/Jun/2019 08:33:41] "GET /js/uncompiled/app.js.map HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2019 08:33:41] "GET /js/uncompiled/app.js HTTP/1.1" 200 -
On the other hand, here is what Chrome attempts:
127.0.0.1 - - [14/Jun/2019 08:34:22] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2019 08:34:22] "GET /js/all.js HTTP/1.1" 200 -
127.0.0.1 - - [14/Jun/2019 08:34:22] code 404, message File not found
127.0.0.1 - - [14/Jun/2019 08:34:22] "GET /uncompiled/app.js.map HTTP/1.1" 404 -
127.0.0.1 - - [14/Jun/2019 08:34:23] code 404, message File not found
127.0.0.1 - - [14/Jun/2019 08:34:23] "GET /favicon.ico HTTP/1.1" 404 -
Chrome appears to be assuming that the sourceURL within js/app.js is relative to index.html, while Firefox instead (correctly, from my perspective) interprets it as being relative to app.js. I suggest that Firefox is correct since this permits any HTML file to include that JS, at any path, and still have the sourcemaps loaded correctly.
Example sources, including two html files at different relative paths: https://github.com/niloc132/sourceurl-and-sourcemapping-url-relative-paths

From the spec (or the copy at https://sourcemaps.info/spec.html):
When the source mapping URL is not absolute, then it is relative to the generated code’s “source origin”. The source origin is determined by one of the following cases:
If the generated source is not associated with a script element that has a “src” attribute and there exists a //# sourceURL comment in the generated code, that comment should be used to determine the source origin. Note: Previously, this was “//# sourceURL”, as with “//# sourceMappingURL”, it is reasonable to accept both but //# is preferred.
If the generated code is associated with a script element and the script element has a “src” attribute, the “src” attribute of the script element will be the source origin.
If the generated code is associated with a script element and the script element does not have a “src” attribute, then the source origin will be the page’s origin.
If the generated code is being evaluated as a string with the eval() function or via new Function(), then the source origin will be the page’s origin.
In the case of js/all.js, it falls in the last case: the source origin will be the page's origin. So it would appears that Chrome is following the spec, even though that might seem counter-intuitive.

Related

Remove /index.html from url for static site

I have a static site on google-cloud-storage bucket.
I rsync my site to the storage bucket with:
args: ["-m", "-h", "Content-Encoding:gzip", "rsync", "-c", "-r", "./folder", "gs://mysite.com"]
I have set in my cloud bucket for website config:
/index.html
This results in:
mysite.com/category/index.html
And from this I want to remove the index.html, so I tried in addition to above args in a second line, the following:
args: ["-h", "Content-Type:text/html", "cp", "./folder/*/index.html", "gs://mysite.com/*"]
But this second args did not work.
How to write the second args so that the index.html is removed from the URL in mysite.com/category/index.html?
The second args are probably working, the thing is that you are using cp which copies files, so you are just uploading the index.html file again.
If you want to remove the index.html you have to use rm:
args: ["-h", "Content-Type:text/html", "rm", "gs://mysite.com/category/index.html"]

Using of standalone model in Catalyst - calling of general methods

I am following receipt of using standalone models in Catalyst in the advent calendar from 2012 here:
http://www.catalystframework.org/calendar/2012/15
and previous days ....
Following this receipt I am transferring existing code from current fat model. I want to have some methods in Model on general level - I expect to put them in this example into lib/StandaloneApp3.pm file (eg. create order means to create record in table order_header, table order_item and table log) and call them from Controller with code:
$c->model('DB')->create_order($params);
I am getting error:
"Can't locate object method "create_order" via package
"WebApp::Model::DB"
When calling function from StandaloneApp3 namespace, this work:
&StandaloneApp3::create_order($params);
I do not think this is good approach as my Controller should connect only to Catalyst Model and not directly to standalone library.
Is there an error in my code to access methods in StandaloneApp3.pm or when using DBIC::Schema I am not expect to call this method? In case I am not supposed to call methods in StandaloneApp3.pm, what is the correct place were to store methods that can write to more tables in one transaction? Any example also for exact calling those methods from outside Catalyst - eg. from command line?
Thank you for your explanation and example.
----------- ADDED CODE -------------
Catalyst model:
file: lib\WebApp\Model\DB.pm:
package WebApp::Model::DB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
1;
Standalone Model:
file: lib/StandaloneApp3.pm
use utf8;
package StandaloneApp3;
use Moose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Schema';
PACKAGE->load_namespaces;
sub create_order {
# in development
return "order_created";
}
PACKAGE->meta->make_immutable(inline_constructor => 0);
1;
Config:
file: webapp.conf
<Model::DB>
schema_class StandaloneApp3
<connect_info>
dsn dbi:SQLite:__path_to(data,database_file2.db)__
</connect_info>
</Model::DB>
Thank you
You are using StandaloneApp3 as your schema class inside of the catalyst model WebApp::Model::DB. That means it's the DBIx::Class schema that is automatically loaded for you. The schema is something like a database object.
To access the schema, you use the schema accessor method on the model.
$c->model('DB')->schema;
So to reiterate, the schema is not part of the model. The model does not inherit from the schema. It just has the schema as an attribute.
Therefore the method create_order in the schema class StandaloneApp3 is not a method on the model WebApp::Model::DB. It's a method on its schema attribute.
$c->model('DB')->schema->create_order;
The easiest way to patch that through would be to make a method create_order in WebApp::Model::DB that calls the method with the same name on the schema.
package WebApp::Model::DB;
# ...
sub create_order {
my $self = shift;
return $self->schema->create_order(#_);
}
I shifted out the $self so I can pass on the rest of the argument list #_ to $self->schema->create_order.
To prove this works, I wrote create_order in StandaloneApp3 like this:
package StandaloneApp3;
# ...
# You can replace this text with custom code or comments, and it will be preserved on regeneration
sub create_order {
# in development
warn "creating order...";
return "order_created";
}
I put the warn in so we can find it in the log that you have in your console later. Note how it's placed underneath DBIC's comment, because we don't want it to be overwritten if we need to regenerate the schema class later in case someone made changes to the database schema.
Finally I'm calling the model method from sub index in the Root controller.
sub index :Path :Args(0) {
my ( $self, $c ) = #_;
$c->model('DB')->create_order;
# Hello World
$c->response->body( $c->welcome_message );
}
If you now request / in your browser (for me that's http://localhost:5000/) now it works, and shows up in the log. Mine is on Windows so it looks a bit odd.
[info] *** Request 1 (0.143/s) [8012] [Sun Nov 27 16:25:59 2016] ***
[debug] Path is "/"
[debug] "GET" request for "/" from "127.0.0.1"
creating order... at lib/StandaloneApp3.pm line 23.
127.0.0.1 - - [27/Nov/2016:16:25:59 +0100] "GET / HTTP/1.1" 200 5477 "-" "Mozill
a/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0
.2840.99 Safari/537.36"
[debug] Response Code: 200; Content-Type: text/html; charset=utf-8; Content-Leng
th: unknown
[info] Request took 0.012028s (83.139/s)
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /index | 0.000545s |
| /end | 0.000340s |
'------------------------------------------------------------+-----------'
But of course if you have a couple of those methods you want to patch through, it gets a bit tedious to write all of them yourself. You could use AUTOLOAD to create methods on the fly, but that seems wrong in this situation, so I'm not going to explain that.
Instead, let's use Catalyst::TraitFor::Model::DBIC::Schema::SchemaProxy, which is a model trait that's included with Catalyst::Model::DBIC::Schema for exactly this situation.
You load it from the configuration file or inside the __PACKAGE__->config(...) in your code. I prefer it there, because it's easier to see what's going on when reading the code, and you can still overwrite it later in the configuration files.
Here is the full WebApp::Model::DB file. I removed the method create_order we put there in the example above, and included the trait configuration instead.
package WebApp::Model::DB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
__PACKAGE__->config(
traits => 'SchemaProxy',
);
1;
That's all you need to change. If you restart the app and request the root / again, it will still work.
[info] *** Request 1 (0.111/s) [6160] [Sun Nov 27 16:43:45 2016] ***
[debug] Path is "/"
[debug] "GET" request for "/" from "127.0.0.1"
creating order... at lib/StandaloneApp3.pm line 23.
127.0.0.1 - - [27/Nov/2016:16:43:45 +0100] "GET / HTTP/1.1" 200 5477 "-" "Mozill
a/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0
.2840.99 Safari/537.36"
[debug] Response Code: 200; Content-Type: text/html; charset=utf-8; Content-Leng
th: unknown
[info] Request took 0.011867s (84.267/s)
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /index | 0.000712s |
| /end | 0.000370s |
'------------------------------------------------------------+-----------'
I suggest you take a few minutes and read the CPAN pages of the modules I linked in this answer. I just did the same. Catalyst can become very complex underneath and it's hard to remember all of it even if you use it a lot, so freshening up on the docs once in a while is a good idea.

github pages 404 jekyll sub pages

Sub pages fail to generate on GitHub, I get 404 errors, when I try to do the same on localhost:4000 it works.
Website Structure:
index.md
-us (folder)
--index.md
--test.md
-uk (folder)
--index.md
--test.md
On local it generates:
www.test.com/index.html
www.test.com/us/index.html
www.test.com/us/test/index.html
www.test.com/uk/index.html
www.test.com/uk/test/index.html
GitHub generates:
www.test.com/index.html
www.test.com/us/index.html
www.test.com/us/test/index.html - 404
www.test.com/uk/index.html
www.test.com/uk/test/index.html - 404
Any ideas?
If your site is in a project repository, his url is like username.github.io/repositoryName.
In _config.yml add baseurl: /repositoryName.
And set your link like this : [Link text]({{ site.baseurl }}{{ page.url }}).
Managed to fix this issue.
For some reason Github pages didn't like my initial structure,
Every subpage should be inside of it's own folder: www.test.com/us/test/index.md
I had to change website structure to it to:
www.test.com/index.md
www.test.com/us/index.md
www.test.com/us/test/index.md
www.test.com/uk/index.md
www.test.com/uk/test/index.md
www.URL.com/index.md - main index page.
www.URL.com/subfolder/index.md - subfolder
www.URL.com/subfolder/subfolder/index.md - 2nd subfolder

Emacs Elnode can't show html pages

I have installed Emacs elnode by Marmalade, and everything looks OK. And I have read the manual carefully.
Now elnode has started, and I can view the folder public_html under .emacs.d\elnode folder.
If I input url http://localhost:8000 in my Chrome, it will show following content:
/
.
..
default-webserver-image.png
test.html
But when I click the test.html file, chrome just can't get the response from elnode. I check my Emacs, the Message file provides two errors:
elnode-error: elnode--sentinel 'open from 127.0.0.1.' for process elnode-webserver-proc 127.0.0.1:2224 with buffer nil
elnode-error: Elnode status: elnode-webserver-proc 127.0.0.1:2224 open from 127.0.0.1
elnode-error: filter: calling handler on elnode-webserver-proc 127.0.0.1:2224
elnode-error: starting HTTP response on elnode-webserver-proc 127.0.0.1:2224
error in process filter: apply: Spawning child process: invalid argument
error in process filter: Spawning child process: invalid argument
I just don't know how to debug it. I also tried elnode-send-file function, it also doesn't work.
But If I run the Hello World example, it works:
(defun my-status-page (httpcon)
(elnode-http-start httpcon 200 '("Content-type" . "text/html"))
(elnode-http-return httpcon "<html><b>HELLO!</b></html>"))
(elnode-start 'my-status-page :port 8010)
The core problem is that Emacs can't send html page!
Is it necessary to do some basic configuration after installing elnode?
Thanks
Water Lin
The newest edition has solved the problem. If you meet the same problem as me, please download the newest edition.
My test environment is Windows7 & Emacs 24.2.1.

javascript in perl code

i using javascript file (json2.js) in perl-cgi code with apache. but when i run it on browser, its unable to find the source and return following error;
'Failed to load resource: the server responded with a status of 404 (Not Found)'
my doumentroot path is : /srv/www/cgi-bin and scripts' path: /srv/www/cgi-bin/scripts
i doing this;
print "<script type='text/javascript' src='./scripts/json2.js'></script>"; # Line 1
print "<script type='text/javascript' language='JavaScript'>
function setDetails(o,json_arrRef,arrSize){
alert('hello='+arrSize+' || ref='+json_arrRef); // till here it works fine
var json_obj = JSON.parse(json_arrRef);
}
</script>";
if I edit Line 1 as
print "<script type='javascript' src='./scripts/json2.js'></script>";
it finds the source but gives following error when 'JSON.parse()' is called;
'Uncaught SyntaxError: Unexpected token ILLEGAL'
am I doing something wrong?
Don't put static files anywhere in or below /cgi-bin/ as servers are often configured to treat that path is a special way
Do get your type attributes correct, the content-type for JavaScript is text/javascript and not just javascript (technically speaking it should be application/javascript, but pretend it is text/javascript for the sake of browsers)
Don't compare JavaScript errors in the browser with Perl code and do look at what the webserver is outputting (i.e. the HTML and JavaScript source and/or which requests give 404 or other HTTP error codes)
Replace "./scripts/json2.js" with "/scripts/json2.js".