Why doesn't browser abort request to a stylesheet when the link element is removed? - html

Consider the following HTML code:
<script>setTimeout(() => document.querySelector('link').remove(), 0);</script>
<link rel="stylesheet" href="http://localhost:8080/test.php">
where http://localhost:8080/test.php is a link to a simple PHP script which just waits 5 seconds (<?php sleep(5);).
The script removes the link tag as expected, but browser doesn't abort the request to the stylesheet. This doesn't make sense, because when the request is complete, browser doesn't apply the styles anyway. Is this a browser bug, or is there an explanation for this behavior in the specification?
This happens in Chrome and Firefox; I didn't test other browsers.

In a browser, the layout engine always parses the HTML from top to bottom, sequentially. However, the request to get CSS happens in parallel because CSS never changes the DOM Tree, there is nothing to worry.
Since style sheets don't change the DOM tree, there is no reason to
wait for them and stop the document parsing
Resource: Read Parsin Scripts > The order of processing scripts and style sheets
The main reason not to abort the CSS request is because it causes no harm. The effort to abort it would be much more painful.
However, note that:
Webkit blocks scripts only when they try to access for certain style
properties that may be effected by unloaded style sheets.
Image: WebKit Layout Engine. Credits - http://taligarsiel.com

Iv'e been reading up on the HTML Parser and your case seems a bit like the chicken and the egg story because naturally a <script> is supposed to block the parsing execution but there are exceptions to this (async & defer attributes)...
what you are doing is abit different ...
by addressing the document in the script tag the browser is forced to stop parsing and create a document with the tag you are addressing without executing the script itself again in the new document and thus requesting its related content before the DOM is able to remove the element ...
the DOM parsing process in the browser consists of a number of steps :
*If the document.write() method was called from script executing inline (i.e., executing because the parser parsed a set of script tags), then this is a reentrant invocation of the parser.
Edit :
A 'script' element is processed as follows:
If the 'script' element's "already processed" flag is true or if the element is not in the document tree, then no action is performed and these steps are ended.
If the 'script' element references external script content, then the external script content using the current value of the 'xlink:href' attribute is fetched. Further processing of the 'script' element is dependent on the external script content, and will block here until the resource has been fetched or is determined to be an invalid IRI reference.
The 'script' element's "already processed" flag is set to true.
If the script content is inline, or if it is external and was fetched successfully, then the script is executed. Note that at this point, these steps may be re-entrant if the execution of the script results in further 'script' elements being inserted into the document.
Note that a load event is dispatched on a 'script' element once it has been processed, unless it referenced external script content with an invalid IRI reference and 'externalResourcesRequired' was set to 'true'.
The Load Event - The event is triggered at the point at which the user agent (Browser) finishes loading the element and any dependent resources (such as images, style sheets, or scripts). In the case the element references a script, the event will be raised only after an attempt to interpret the script has been made. Dependent resources that fail to load will not prevent this event from firing if the element that referenced them is still in the document tree unless they are designated as externalResourcesRequired. The event is independent of the means by which the element was added to DOM tree.
If you are asking why the event loop is built that way I can't give you a definitive answer nor can I suggest a better way for it to operate but in the comments you asked what the specifications say about this condition and the specifications state that it is due to historical reasons as stated below :
HTML 5.1 W3C Recommendation, 1 November 2016
7. Web application APIs
7.1.4.2. Processing model
Some of the algorithms in this specification, for historical reasons, require the user agent to pause while running a task until a condition goal is met. This means running the following steps:
If necessary, update the rendering or user interface of any Document or browsing context to reflect the current state.
Wait until the condition goal is met. While a user agent has a paused task, the corresponding event loop must not run further tasks, and any script in the currently running task must block. User agents should remain responsive to user input while paused, however, albeit in a reduced capacity since the event loop will not be doing anything.

Related

Reagent get element contents before mount

I'm adding some reagent to an application in which some hiccup rendering is already done on the server from a database. Obviously react then hooks into the html that it sees & mounts.
I want to do some progressive enhancement, i.e., a react/reagent component should mount but I also need the original text of the div it's going to mount on, this is put there by the database. So to react it's in the static html it is about to overwrite when it mounts. I want to save that element's contents before it's "deleted".
Here's what's not working
(defn by-id [id] (js/document.getElementById id))
(when-let [el (by-id "lesson-app")] ; only mount when this el is present
(let [lesson-text (by-id "lesson-app")] ; try to get el contents before mount
(console.log lesson-text) ; <- this logs contents *after* mount!!
(rdom/render [lesson-app] el))) ; mount the component
What's logged to console here is the dom element after mount. Why is that?
Was wondering if I could use a form-2 component and grab the contents in the let. That's not working for me though, interesting to know why if anyone can explain.
Update
I've succeeded in passing in text as an html attribute, as described here. But that means for progressive enhancement I need to render the text twice, once as an attr & once as the normal text content.
Update 2
I'm getting the feeling it may be for reasons of convention or encouraged idiom and/or perhaps speed that react does not let you pass in html element content (it clearly doesn't violate the laws of physics to do so). The slight cost if this is correct is that for a progressive app we must duplicate the text as both html element content and a data- attribute, but that's not terrible at least for my current case.
This functionality isn't supported by react.
We use an html data- attribute instead.
For example:
(defn ^:export run []
(when-let [el (by-id "lesson-app")]
(let [data-text (.getAttribute el "data-text")]
(rdom/render [lesson-app data-text] el))))

How does browser loads DOM and CSSOM partially?

First let me give you simple overview how it loads, then ill ask question regarding that.
Browser Fetch HTML => parse html => create nodes => parse nodes and start converting them to Dom elements => finds style node so start creating CSSOM => on finishing parsing if there was style tag it waits to let it construct CSSOM tree => once both are finished it merges both, DOM and CSSOM, and fires DOMContentLoaded Event.
So in summary as soon as CSSOM is ready browser starts rendering and Dom can incrementally be added.
This is all fine, but how does the flow go when browser starts rendering page when not the whole html is loaded..(for example in nodejs you can partial html then wait 2s and then send more)
What if there was another style tag at the bottom of the page. Not having received all html, and no css browser would start rendering, but from my understanding rendering only occurs after cssom has been completely built.
What happens to script tag, if css isn't done processing script tag isn't executed and thus also stops parsing. JS is ran after CSSOM is complete.
Things may block the DOMContentLoaded Event, but that does not prevent rendering of the incomplete page. That can be important for very long pages streamed from a slow server.
Browsers can and do interleave script execution, re-styling, rendering with the document parsing. This can be trivially shown by executing javascript in the <head> and querying the DOM, you will see that the document will not have all of its nodes (possibly not even a body element) before the DOMContentLoaded event has fired.
You have to think of document construction more as a stream than sequentially executed blocks that run to completion before the next block starts.
CSSOM stops parsing. Thus execution of subsequent script tags, and also delays rendering.
Script tags before style tags will execute before CSS is loaded into CSSOM from style tags afterwards.
Style tags that come after script tags will alter CSSOM. And if script accessed styles that are being altered then what it read is outdated. Order matters.
Parsing is stopped not just rendering.
JavaScript blocks parsing because it can modify the document. CSS
can’t modify the document, so it seems like there is no reason for it
to block parsing, right?
However, what if a script asks for style information that hasn’t been
parsed yet? The browser doesn’t know what the script is about to
execute—it may ask for something like the DOM node’s background-color
which depends on the style sheet, or it may expect to access the CSSOM
directly.
Because of this, CSS may block parsing depending on the order of
external style sheets and scripts in the document. If there are
external style sheets placed before scripts in the document, the
construction of DOM and CSSOM objects can interfere with each other.
When the parser gets to a script tag, DOM construction cannot proceed
until the JavaScript finishes executing, and the JavaScript cannot be
executed until the CSS is downloaded, parsed, and the CSSOM is
available
.
https://hacks.mozilla.org/2017/09/building-the-dom-faster-speculative-parsing-async-defer-and-preload/
A few important facts:
Event DOMContentLoaded is fired when the document has been fully parsed by the main parser AND the DOM has been completely built.
Any normal script (not async or deferred) effectively blocks DOM construction. The reason is that a script can potentially alter DOM.
Referencing a stylesheet is not parser-blocking nor a DOM-construction-blocker.
If you add a <script> (be it external or inline) after referencing a CSS, the execution (not fetching) of the script is delayed until fetching and parsing of the CSS has been finished even if the script's fetch finishes sooner. The reason is that the scripts may be dependent on the to-be-loaded CSS rules. So the browser has to wait.
Only in this case, a CSS blocks the document parser and DOM construction indirectly.
When the browser is blocked on a script, a second lightweight parser scans the rest of the markup looking for other resources e.g. stylesheets, scripts, images etc., that also need to be retrieved. It's called "Pre-loading".

Meaning of ./ in the below HTML code

Hi Friends...
What will happen when submit button is clicked...
<form name="form" action="./" method="post">
What action will be done for ./
Kindly comment the relevant answers...
Thanks in Advance
It will ask the server for the default file in the current directory. Usually that is index.html, index.htm, index.php, ...
But depending on the setup / configuration of the server (including redirects), it could take you to http://www.monkeybusiness.tv/spamalot.asp?user=me&password=secret
There is no way of knowing.
The meaning of # as a URL reference (whether as action or formaction attribute value or otherwise) is a reference to the start of the current base document. The base document is the current document, unless a <base href=...> tag has been set.
What happens depends on the situation. Typically, the browser requests for the page again with a query part in the URL (and the page is loaded again, which may imply that client-side scripts are run), but if the same query had been used earlier, the browser probably uses its cache. Moreover, as the start of the document is referred to, focus on any form element is lost and the page may scroll backwards.
So although # is fairly common in some coding styles, it is reliable; its purpose is better achieved using client-side event handlers.
The formaction attribute has a meaning only for submit buttons. A text input element does not constitute a submit button, even though it may trigger form submission, so here the attribute is ignored.

what is the # symbol in the url

I went to some photo sharing site, so when I click the photo, it direct me to a url like
www.example.com/photoshare.php?photoid=1234445
. and when I click the other photo in this page the url become
www.example.com/photoshare.php?photoid=1234445#3338901
and if I click other photos in the same page, the only the number behind # changes. Same as the pretty photo like
www.example.com/photoshare.php?album=holiday#!prettyPhoto[gallery2]/2/
.I assume they used ajax because the whole page seems not loaded, but the url is changed.
The portion of a URL (including and) following the # is the fragment identifier. It is special from the rest of the URL. The key to remember is "client-side only" (of course, a client could choose to send it to the server ... just not as a fragment identifier):
The fragment identifier functions differently than the rest of the URI: namely, its processing is exclusively client-side with no participation from the server — of course the server typically helps to determine the MIME type, and the MIME type determines the processing of fragments. When an agent (such as a Web browser) requests a resource from a Web server, the agent sends the URI to the server, but does not send the fragment. Instead, the agent waits for the server to send the resource, and then the agent processes the resource according to the document type and fragment value.
This can be used to navigate to "anchor" links, like: http://en.wikipedia.org/wiki/Fragment_identifier#Basics (note how it goes the "Basics" section).
While this used to just go to "anchors" in the past, it is now used to store navigatable state in many JavaScript-powered sites -- gmail makes heavy use of it, for instance. And, as is the case here, there is some "photoshare" JavaScript that also makes use of the fragment identifier for state/navigation.
Thus, as suspected, the JavaScript "captures" the fragment (sometimes called "hash") changing and performs AJAX (or other background task) to update the page. The page itself is not reloaded when the fragment changes because the URL still refers to the same server resource (the part of the URL before the fragment identifier).
Newer browsers support the onhashchange event but monitoring has been supported for a long time by various polling techniques.
Happy coding.
It's called the fragment identifier. It identifies a "part" of the page. If there is an element with a name or id attribute equal to the fragment text, it will cause the page to scroll to that element. They're also used by rich JavaScript apps to refer to different parts of the app even though all the functionality is located on a single HTML page.
Lately, you'll often see fragments that start with "#!". Although these are still technically just fragments that start with the ! character, that format was specified by Google to help make these AJAXy pseudo-pages crawlable.
The '#' symbol in the context of a url (and other things) is called a hash, what comes after the hash is called a fragment. Using JavaScript you can access the fragment and use its contents.
For example most browsers implement a onhashchange event, which fires when the hash changes. Using JavaScript you can also access the hash from location.hash. For example, with a url like http://something.com#somethingelse
var frag = location.hash.substr(1);
console.log(frag);
This would print 'somethingelse' to the console. If we didn't use substr to remove the first character, it frag would be: '#somethingelse'.
Also, when you navigate to a URL with a hashtag, the browser will try and scroll down to an element which has an id corresponding to the fragment.
http://en.wikipedia.org/wiki/Fragment_identifier
It is the name attribute of an anchor URL: http://www.w3schools.com/HTML/html_links.asp
It is used to make a bookmark within an HTML page (and not to be confused with bookmarks in toolbars, etc.).
In your example, if you bookmarked the page with the # symbol in the URL, when you visit that bookmark again it will display the last image that you viewed, most likely an image that has the id of 3338901.
hey i used sumthing like this .... simple but useful
location.href = data.url.replace(/%2523/, '%23');
where data.url is my original url . It substitutes the # in my url

Oracle Forms 10g - Closing IE after opening msg file

We are using web.show_document built-in in Oracle forms (web.show_document('file:///file_name','_blank') ) to open outlook msg files stored at a location.
While opening msg files, a new IE browser gets open along with msg file. User need to close this additional browser.
I infer that you do not wish the separate IE browser to be opened in the first place? If that is the case, then there is another option than what I present below. Read on.
Option 1:
From the Forms documentation, the target ("_blank") parameter has a few different possible values.
target  Datatype is VARCHAR2. Specifies one of the following targets:
'_self' Causes the document to load
into the same frame or window as the
source document.
'_parent' Causes the target document
to load into the parent window or
frameset containing the hypertext
reference. If the reference is in a
window or top-level frame, it is
equivalent to the target _self.
'_top' Causes the document to load
into the window containing the
hypertext link, replacing any frames
currently displayed in the window.
'_blank' (default) Causes the
document to load into a new, unnamed
top-level window.
Note that these targets are lowercase and enclosed in single quotation marks.
Option 2:
If you would rather not have an IE window open up at all, there is a package in WEBUTIL.PLL called WEBUTIL_HOST. It would allow you to open a file from the perspective of the client. I am going out on a limb here an making an assumption that the URI you mentioning as 'file:///file_name' is a file path that is likely accessible from the client already.
Hope this helps, I made a few assumptions here. If you provide some more info on the specific situation, that would be helpful.