xerta555 / 500pxOnNewTab

WebExtension for Firefox in dev stage
1 stars 1 forks source link

About this addon #1

Open xerta555 opened 6 years ago

xerta555 commented 6 years ago

Here @jingyu9575,

We can continue to speack here to avoid spamming your repo. Don't hesitate to suggest to me some methods

Thank you in advance :)

jingyu9575 commented 6 years ago

In background, the WE check if there are already one or more wallpapers in the walls folder, if yes rename them to avoid any conflits with next steps (renaming them with higher numbers), download every 3 hours the 3 thirst wallpapers from the 500px URL (http://feed.500px.com/500px-best) in the walls folder of the addon, and apply the first one to the background of the internal NewTab page of Firefox.

The first thing to consider is whether it is possible to customize the new tab page. The WebExtensions API theme_ntp_background for setting the new tab background is still under development, and it is unclear whether dynamic images (that are not bundled in the extension) are allowed.

Currently, there is another API chrome_url_overrides that changes the new tab entirely to a page provided by the extension. The extension New Tab Override uses this API. With this method, the background image can be changed freely, but the search bar and the top sites will not show (unless you reimplement them in the extension), as the new tab is replaced.


Another difficulty is that WebExtensions cannot access the filesystem. Without external programs, the only way to write files is using the built-in download manager, which can put files in the default download folder, or show a dialog where the user chooses the location. Also, there is no API to read the file back without user interaction.

Therefore, you have to use other storage methods. Common storage methods of WebExtensions are browser.storage and IndexedDB. You can put the images in one of them in the background script, and then read them in the provided new tab page.


To download the images, the background script must access the http://feed.500px.com/500px-best website. canvas.toDataURL does not work here (it is for getting image data from a canvas element). You can use the fetch API or XMLHttpRequest to access the website. Extract the image URLs, fetch again to get the image content, and then you can put it to the storage.


Overall I think the download and storage parts are not difficult with the right API. The problem is how to apply it to the new tab page. Do you plan to use chrome_url_overrides (with the disadvantage above), or wait for the theme_ntp_background API?

xerta555 commented 6 years ago

The first thing to consider is whether it is possible to customize the new tab page. The WebExtensions API theme_ntp_background for setting the new tab background is still under development, and it is unclear whether dynamic images (that are not bundled in the extension) are allowed.

Ok effectivly i see that the API willn't accept to load local files (because inter-process performances issues apparently). Personally i don't think that is for now the best way as some infos aren't finished.

Currently, there is another API chrome_url_overrides that changes the new tab entirely to a page provided by the extension. The extension New Tab Override uses this API. With this method, the background image can be changed freely, but the search bar and the top sites will not show (unless you reimplement them in the extension), as the new tab is replaced.

Ok why not, as u say, it will add to me more dev steps but i don't think that i will become a problem.. I think that i will start on this idea.

Another difficulty is that WebExtensions cannot access the filesystem. Without external programs, the only way to write files is using the built-in download manager, which can put files in the default download folder, or show a dialog where the user chooses the location. Also, there is no API to read the file back without user interaction. Therefore, you have to use other storage methods. Common storage methods of WebExtensions are browser.storage and IndexedDB. You can put the images in one of them in the background script, and then read them in the provided new tab page.

Ok, but i said, i don't have knowledges in js linguage, and it appear very strange to me. Can we use another linguage to build a WebExtension without calling sub-process to call an exe or an sh file ?

To download the images, the background script must access the http://feed.500px.com/500px-best website. canvas.toDataURL does not work here (it is for getting image data from a canvas element). You can use the fetch API or XMLHttpRequest to access the website. Extract the image URLs, fetch again to get the image content, and then you can put it to the storage.

Hm hm ok but as i said before, i have no idea on how create my WE, i just have the idea. I can imagine with some js scripts how i could write some stuff, but nothing more.

Overall I think the download and storage parts are not difficult with the right API. The problem is how to apply it to the new tab page. Do you plan to use chrome_url_overrides (with the disadvantage above), or wait for the theme_ntp_background API?

I think that i will use the chrome_url_overrides API to avoid any bad news from Mozilla devs about the new API (as for the old API addons migration and no support of old APIs).

About managing files, i currently use this method supported by Mozilla: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/FileGuide/MoveCopyDelete Ok its maybe not a powerfull methods, but it's clearly explained and easy to understand..

Do u know a website on wich i could learn "quickly" the js linguage ? (if we can only use this linguage in WE addon)

jingyu9575 commented 6 years ago

Can we use another linguage to build a WebExtension without calling sub-process to call an exe or an sh file ?

Only JavaScript is supported*. There are some languages that can compile (be converted) to JavaScript e.g. TypeScript used by multithreaded-download-manager, but they are more difficult and less popular than JavaScript.

* In theory some other languages like C++ are supported via WebAssembly, but it is still at an early stage of development, and is very difficult to work with WebExtensions.

Mozilla/Tech/XUL/FileGuide/MoveCopyDelete

XUL/XPCOM is the underlying technology for legacy extensions, and is not supported by WebExtensions. Many APIs in XUL/XPCOM have no equivalents in WebExtensions, including File IO.

In Mozilla docs, the legacy APIs are often listed under Mozilla/Tech/XUL or Mozilla/Tech/XPCOM, while WebExtensions APIs are under Mozilla/Add-ons/WebExtensions. In addition, common HTML/CSS/JS things under Web can usually be used in WebExtensions.

a website on wich i could learn "quickly" the js linguage

I think Mozilla's MDN docs is a good resource. W3Schools is also popular for beginners.

The MDN docs about WebExtensions have some guides and examples. I recommend following them to create and run a simple extension, to see how things work.

xerta555 commented 6 years ago

Only JavaScript is supported*. There are some languages that can compile (be converted) to JavaScript e.g. TypeScript used by multithreaded-download-manager, but they are more difficult and less popular than JavaScript.

  • In theory some other languages like C++ are supported via WebAssembly, but it is still at an early stage of development, and is very difficult to work with WebExtensions.

Ok understood. Having several knowledges in shell linguage, it's really different.

XUL/XPCOM is the underlying technology for legacy extensions, and is not supported by WebExtensions. Many APIs in XUL/XPCOM have no equivalents in WebExtensions, including File IO. Ah yeah shit! So i must to find a way to do theses sort of steps in JS linguage..

In Mozilla docs, the legacy APIs are often listed under Mozilla/Tech/XUL or Mozilla/Tech/XPCOM, while WebExtensions APIs are under Mozilla/Add-ons/WebExtensions. In addition, common HTML/CSS/JS things under Web can usually be used in WebExtensions.

:+1:

I think Mozilla's MDN docs is a good resource. W3Schools is also popular for beginners.

The MDN docs about WebExtensions have some guides and examples. I recommend following them to create and run a simple extension, to see how things work.

Thank you very much i will take a look in them.

According my manifest.json, i get this following error when i try to load it temporary in Firefox Beta: JSON.parse: expected ',' or '}' after property value in object at line 50 column 2 of the JSON data I don't understand what cause this error, i have try several things but nothing works.. Can u take a look in that please ?

And about node.js, it's supported by WE APIs ?

jingyu9575 commented 6 years ago

See #2 for the suggested changes.

The error message means at that line, there must be a , or }. If that value is the last value, the next symbol should be } to close the bracket. Otherwise, , is mandatory between key-value pairs.

I suggest using a programming editor, which can show syntax errors clearly. Here is this file on Visual Studio Code: default

xerta555 commented 6 years ago

See #2 for the suggested changes.

The error message means at that line, there must be a , or }. If that value is the last value, the next symbol should be } to close the bracket. Otherwise, , is mandatory between key-value pairs.

I suggest using a programming editor, which can show syntax errors clearly. Here is this file on Visual Studio

About the editor program, u suggest me to install wich one, excluding Viusual Studio, to keep some disk space ?

Thank you very much about your fixs :+1:

jingyu9575 commented 6 years ago

Visual Studio Code (VSCode) is a different program from Visual Studio. It is 45 MB to download and 227 MB installed.

For smaller alternatives, I heard Sublime Text is good. The free version has no function/time limit but occasionally shows upgrade/register popups.

Notepad++ is also recommended. It is free and open source, but Windows only.

node.js

It is a different JavaScript environment mainly used in servers and Electron programs. Its APIs cannot be used in extensions.

xerta555 commented 6 years ago

Visual Studio Code (VSCode) is a different program from Visual Studio. It is 45 MB to download and 227 MB installed.

I'm actually installing VS 2017 with JS components :)

For smaller alternatives, I heard Sublime Text is good. The free version has no function/time limit but occasionally shows upgrade/register popups. Notepad++ is also recommended.

Ok, it's strange because i have test my manifest.json (i deleted my initial addon folder, download the .zip file from my github and open it again with notepad++ => Invalide extension, same with Sublime Text, i open the manifest.json (wich previously worked fine on Firefox), close it from Sublime and reload it from Mozilla => same error, very very strange.

xerta555 commented 6 years ago

@jingyu9575 Now my WE addon won't be translate, for exemple, i have translated the name and the description in the French and English folder in _locales folder but they aren't applied.

And i have again the error message "Extension is invalid" from about:debugging FF page, it's very boring this json file, about you, it's due to a wrong tabulation or what ?

Thank u in advance.

xerta555 commented 6 years ago

Now my WE addon won't be translate, for exemple, i have translated the name and the description in the French and English folder in _locales folder but they aren't applied.

After several attempt to fix that, i have finally understand the way to make locales to working!

And i have again the error message "Extension is invalid" from about:debugging FF page, it's very boring this json file, about you, it's due to a wrong tabulation or what ?

I have also fix this importation issue with the Browser Consol (Ctrl+MAJ+J), really usefull to get some prcious informations.

Now i begin the serious work :P

xerta555 commented 6 years ago

@jingyu9575 I am actually hesitate to use the new theme_ntp_background Firefox API, because a very recent answer from Tim Nguyen (https://bugzilla.mozilla.org/show_bug.cgi?id=1470764 say that it will possible to using an img file in the addon, and it willn't possible to load external img file (from URL) due to heavy process communication (the download time i think..).

Actually i have done to set an img file on the new tab page, but my center class setting won't work because the img file isn't centered.

I think that i should learn on how to write an clickable menu, it's appear as a abstract way on how it works, i actually read the MDN Web Docs and stackoverflow js scripts exemples, but haven't got knowledges in css and js, it's difficul to understand how to make all them works.

Also, i try to apply a translation string to the title of the newtab, but nothing works. I don't know if it's related to the API used for the NewTab or if it's only depending on the html/js ?

jingyu9575 commented 6 years ago

I downloaded the latest source, but the image was not shown at all. You need to move the folder walls and img into the src folder, because Firefox will not use anything outside the parent folder of manifest.json (src). You can also move everything in src to the root folder.


it will possible to using an img file in the addon

The problem is whether new images downloaded from 500px will work. Here "an img file in the addon" means the image files we put in the extension's source like walls/Image1.jpeg. Once the extension is installed, no new files can be added to it, and the downloaded images must be put in the extension's storage instead. Tim still has not answered whether images from storage can be used or not.

"Data URLs" are not regular website URLs, but a specific format for resources. For other theme values, this format is used to apply images not bundled in the extension.


the img file isn't centered

class="center" does not do anything by itself.

To build a website or an extension, 3 languages are used:

  1. HTML to define the content of web pages
  2. CSS to specify the layout of web pages
  3. JavaScript to program the behavior of web pages

Here, the <img> tag is the content: the page has an image and the source file is "../walls/Image1.jpeg".

"Centering the image element" is a layout requirement, so it belongs to the CSS file. First create a CSS file css/NewTab.css and load it in the <head> tag of NewTab.html:

<link rel="stylesheet" href="../css/NewTab.css">

The CSS file contains style rules, and they are applied to elements in the HTML file. An important question is: how can we write the rules, so that they are only applied to the elements we want? This topic is called "CSS selectors", and some basic methods are:

  1. p { color: red; } This rule applies to all <p> elements, and set their color to red.
  2. #para1 { color: red; } This rule applies to the element that has id="para1" e.g. <p id="para1">. Each element can only have one id, and duplicate id values are not allowed, so this rule only applies to at most 1 element.
  3. .r { color: red } This rule applies to all elements that has class="r". One element can have multiple classes (class="r c2 myclass3"), and multiple elements can have the same class value, so this is the most flexible method.

Therefore, the meaning of class="center" is: if there is a CSS rule .center { ... }, apply it to this element. If you found this on another project, it probably has a CSS file that contains a .center rule, which will do the actual centering.

Here we need to find the rules that can center the element. Ironically, for old browsers, the rules for centering things can be very difficult and there are multiple-page guides for that (1, 2, 3).

Fortunately we only need to support modern browsers (Firefox 57+) here, and in my experience, I suggest the following tools in modern browsers to solve most layout problems:

  1. Flexbox, for 1D (one-dimension) layout;
  2. Grid, for complex 2D layout;
  3. Position and z-index, for overlapping elements.

Centering an element is a simple (single-element) 1D layout problem, so I would use flexbox. Use the display: flex rule on the container (<body> here) to enable flexbox, and pick the flexbox rules of horizontal centering and vertical centering:

display: flex;
align-items: center;
justify-content: center;

These rules need to be applied to the container. The methods are discussed above. For example, add a class <body class="center-container">, and write CSS:

.center-container {
    display: flex;
    align-items: center;
    justify-content: center;
}

Finally there are some boilerplate code to force using the entire page height and remove margins (by default the content shrinks to reduce page height):

html, body {
    height: 100%;
    margin: 0;
}

I have pushed the changes to my fork. If your code still does not work, look there for an example.

jingyu9575 commented 6 years ago

clickable menu

Which menu? Did you mean the popup page of the toolbar button? Just fix the manifest and add content to the HTML file.

"browser_action": {
  "default_popup": "html/Actions.html",
  "browser_style": true
},

apply a translation string to the title of the newtab

The syntax __MSG_messageName__ only works in manifest.json. In other places, you need the JavaScript API i18n.getMessage.

xerta555 commented 6 years ago

I downloaded the latest source, but the image was not shown at all. You need to move the folder walls and img into the src folder, because Firefox will not use anything outside the parent folder of manifest.json (src). You can also move everything in src to the root folder.

Ok, noted, i already have made that but i have got made the changes on the repo.

The problem is whether new images downloaded from 500px will work. Here "an img file in the addon" means the image files we put in the extension's source like walls/Image1.jpeg. > Once the extension is installed, no new files can be added to it, and the downloaded images must be put in the extension's storage instead. Tim still has not answered whether images from storage can be used or not.

"Data URLs" are not regular website URLs, but a specific format for resources. For other theme values, this format is used to apply images not bundled in the extension.

Ah ok, so the basic feasibility of operation is called into question in this case, which is not good news.

the img file isn't centered class="center" does not do anything by itself. To build a website or an extension, 3 languages are used: HTML to define the content of web pages CSS to specify the layout of web pages JavaScript to program the behavior of web pages

Here, the tag is the content: the page has an image and the source file is "../walls/Image1.jpeg".

"Centering the image element" is a layout requirement, so it belongs to the CSS file. > First create a CSS file css/NewTab.css and load it in the tag of NewTab.html:

The CSS file contains style rules, and they are applied to elements in the HTML file. An important question is: how can we write the rules, so that they are only applied to the elements we want? This topic is called "CSS selectors", and some basic methods are:

p { color: red; } This rule applies to all

elements, and set their color to red. #para1 { color: red; } This rule applies to the element that has id="para1" e.g.

id="para1">. Each element can only have one id, and duplicate id values are not allowed, so this rule only applies to at most 1 element. .r { color: red } This rule applies to all elements that has class="r". One element can have multiple classes (class="r c2 myclass3"), and multiple elements can have the same class value, so this is the most flexible method.

Therefore, the meaning of class="center" is: if there is a CSS rule .center { ... }, apply it to this element. If you found this on another project, it probably has a CSS file that contains a .center rule, which will do the actual centering.

Here we need to find the rules that can center the element. Ironically, for old browsers, the rules for centering things can be very difficult and there are multiple-page guides for that (1, 2, 3).

Fortunately we only need to support modern browsers (Firefox 57+) here, and in my experience, I suggest the following tools in modern browsers to solve most layout problems:

Flexbox, for 1D (one-dimension) layout; Grid, for complex 2D layout; Position and z-index, for overlapping elements.

All noted :+1: :+1:

These rules need to be applied to the container. The methods are discussed above. For example, add a class , and write CSS:

.center-container { display: flex; align-items: center; justify-content: center; }

Finally there are some boilerplate code to force using the entire page height and remove margins (by default the content shrinks to reduce page height):

html, body { height: 100%; margin: 0; }

Applied to my local files.

Which menu? Did you mean the popup page of the toolbar button? Just fix the manifest and add content to the HTML file.

Yes absolutly !

The syntax __MSG_messageName__ only works in manifest.json. In other places, you need the JavaScript API i18n.getMessage.

Ah ok, it's not explained in MDN docs webpages, so now it's clear for me thanks.

For now, my addon looks like that: __msg_newtabtitle__ - mozilla firefox

I don't know if there is an error, because this: "browser_action": { "default_popup": "html/Actions.html", "browser_style": true }, Is noted in the New Tab FF page, and in addon toolbar icon click. And about my toolbar icon, i don't arrive to changing the icon of my addon in the toolbar.

Thank you again for your help :+1: :1st_place_medal:

jingyu9575 commented 6 years ago

I meant fixing the code "browser_action": { "default_popup": "html/Actions.html", "browser_style": true }, in manifest.json, so "default_popup" refers to the HTML file you want to show in the popup. Then put content in the HTML file ("html/Actions.html").

changing the icon of my addon in the toolbar

See the doc. Toolbar icons are called "browser actions" in WebExtensions.

xerta555 commented 6 years ago

I meant fixing the code "browser_action": { "default_popup": "html/Actions.html", "browser_style": true }, in manifest.json, so "default_popup" refers to the HTML file you want to show in the popup. Then put content in the HTML file ("html/Actions.html").

Thank you now i see the popup :) But now i don't arrive to find how to make the sentences translated, i try with the i18n.getMessage() API, but i must to set it in the CSS or in the JS file Action file ? (i think in the js file but not sure..).

See the doc. Toolbar icons are called "browser actions" in WebExtensions.

Yeah absolutly i helped myself with the beastify MND WE exemple but really i don't arrive to get my 500px icon in my FF bar with my other addons..

Concerning the choice between the two API to apply the wallpaper as background of the NewTab, i prefere to wait that the new FF API was done to finally deciding on wich i use for that.

jingyu9575 commented 6 years ago

set it in the CSS or in the JS file Action file

Yes the JS file. For example, to change the text content of the element with id "error-content" to the translated message "description":

document.querySelector('#error-content').textContent = browser.i18n.getMessage('description')

Some relevant docs: querySelector, querySelectorAll, textContent, i18n.getMessage

get my 500px icon in my FF bar with my other addons

The current code works for me: default

xerta555 commented 6 years ago

@jingyu9575 Hello, i'm trying to make a popup menu with translated items in it: https://github.com/xerta555/500pxOnNewTab/blob/master/src/html/Actions.html

But i get that.. efforgprivacybadger at update-firefox-min-version - mozilla firefox

Can u say to me how make it works please ?

xerta555 commented 6 years ago

Yes the JS file. For example, to change the text content of the element with id "error-content" to the translated message "description":

document.querySelector('#error-content').textContent = browser.i18n.getMessage('description')

Ok i begin to understand now..

Some relevant docs: querySelector, querySelectorAll, textContent, i18n.getMessage

Thank you very much one more time :+1:

xerta555 commented 6 years ago

Curiously my popup don't work anymore after close and open again my files and Firefox, i had edit Actions.html and Action.js and i get an display error, but even copy/past our last fixs, i get the same issue: about this addon issue 1 xerta555500pxonnewtab - mozilla firefox

Additionally, i tried to add a second line for the About link in the popup, but none of the ideas i tried were conclusive, so i return to just one link in the popup-menu for now, for the second link, it must to openning an About.html file located in the same folder as Options.html, i think i should add this line in Actions.js:

document.querySelector('#options-content').textContent = browser.i18n.getMessage('PopupToAbout')

And this in my Actions.html:

<a href="About.html" aria-label="aria-labelledby" data-tip-position="under"</a>

But i'm not sure..

jingyu9575 commented 6 years ago

popup don't work anymore

Your Action.js has syntax error, which prevents Firefox from loading the file.

The renderPopup function is probably borrowed from uBlock Origin, but the original code has another elem.classList.toggle call, and its ( matches the runaway ) in your code.

Again, I suggest keeping the extension minimal and removing code from other extensions. That renderPopup function is probably useless for your extension, but errors and side-effects in it affect your extension and make it too complicated to understand.

default


add a second line

This code also has syntax error:

<a href="About.html" aria-label="aria-labelledby" data-tip-position="under"</a>

A > symbol is missing. Unlike JS, syntax errors in HTML will not prevent it from loading, but the browser will interpret it in the wrong way, and the result will be unexpected.

<a href="About.html" aria-label="aria-labelledby" data-tip-position="under"></a>

The aria-label attribute is an accessibility feature (e.g. screen readers), and the value here is probably wrong. Attributes that start with "data" have no effects, and are only used for storing values that can be read in JS.

I suggest simplifying the code, and then add the "About" link:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link href="/css/Action.css" rel="stylesheet" />
    <title></title>
</head>
<body>
    <a href="Options.html" id="options-link"></a>
    <a href="About.html" id="about-link"></a>

    <script src="/js/Action.js"></script>
</body>
</html>

Here, <!DOCTYPE html> should be put on the beginning of every HTML file. This instructs browsers to use the latest HTML standard. Without this line, browsers will use the old "Quirks Mode", and there will be a lot of quirks that are difficult to fix.

The line <meta charset="utf-8"> is just short for <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">.

I added id for the two links.

In Action.js:

document.querySelector('#options-link').textContent = browser.i18n.getMessage('Click_Popup')
document.querySelector('#about-link').textContent = browser.i18n.getMessage('PopupToAbout')

document.querySelector finds an element. The rules are the same as the CSS selector rules, so '#options-link' means the element with id="options-link", i.e. the first link. Use browser.i18n.getMessage to get the translation, and put it into the element's textContent.

jingyu9575 commented 6 years ago

Note: semicolons (;) are optional in JS. The code

document.querySelector('#options-link').textContent = browser.i18n.getMessage('Click_Popup')
document.querySelector('#about-link').textContent = browser.i18n.getMessage('PopupToAbout')

is equivalent to:

document.querySelector('#options-link').textContent = browser.i18n.getMessage('Click_Popup');
document.querySelector('#about-link').textContent = browser.i18n.getMessage('PopupToAbout');

Some people use semicolons, while some people do not use them.

xerta555 commented 6 years ago

With an Actions.html like that: a_2

I get only the initial link to the Options.html file, i'm sure that it happen again due to a syntax error in the html file.

There is my actual Actions.js file: b

About this last one, i don't think that there is an error, but Visual Studio tell me that there are 3 (ESLint) Missins semicolon..

xerta555 commented 6 years ago

Your Action.js has syntax error, which prevents Firefox from loading the file.

The renderPopup function is probably borrowed from uBlock Origin, but the original code has another elem.classList.toggle call, and its ( matches the runaway ) in your code.

Ok, and as i use this addon, it could make error(s).

Again, I suggest keeping the extension minimal and removing code from other extensions. That renderPopup function is probably useless for your extension, but errors and side-effects in it affect your extension and make it too complicated to understand.

The student will listen to the teacher on the subject :100:

This code also has syntax error:

<a href="About.html" aria-label="aria-labelledby" data-tip-position="under"

A > symbol is missing. Unlike JS, syntax errors in HTML will not prevent it from loading, but the browser will interpret it in the wrong way, and the result will be unexpected.

Fixed, thanks!

I suggest simplifying the code, and then add the "About" link

Noted.

Here, <!DOCTYPE html> should be put on the beginning of every HTML file. This instructs browsers to use the latest HTML standard. Without this line, browsers will use the old "Quirks Mode", and there will be a lot of quirks that are difficult to fix.

The line is just short for .

Again more crucial HTML rules that i discover thanks to you!

xerta555 commented 6 years ago

@jingyu9575 Hello,

I'm currently trying to center a /img/background.jpg in the background of the menu in Firefox icons bar, my actuall /src/css/Action.js file:

.square { width: 320px; height: 176px; background-image: url(/img/background.jpg); border: solid 2px; text-shadow: white 0px 0px 2px; font-size: 16px; background-size: 150px; background-position-y: center; background-size: contain; }

Actually it's displaied like that for me: about this addon issue 1 xerta555500pxonnewtab - mozilla firefox

And about my strings elements (the menu), i get in the Navigation console the following error: TypeError: document.querySelector(...) is null

I understand by this message that the querySelector document.querySelector('#options-content').textContent = browser.i18n.getMessage('Click_Popup') is now obsolete ?

Or maybe that the location of the <body background="/img/background.jpg"> in my Actions.html file isn't in the right path/location ? I tried initialy to defining my background img as parent of the popup-content div but apparently it must to be moved between another HTML tags or some other modifications are needed.

jingyu9575 commented 6 years ago

I only saw a blank page, and did not see the TypeError. Have you uploaded the code to this repo?

default

If you are not using the Team Explorer in Visual Studio: this is a feature to integrate project with version control tools and websites such as GitHub. Click the "Open in Visual Studio" button in GitHub. Visual Studio will open and Team Explorer will ask for a new location to download the repo.

default

In this new project, you can commit the local changes and push them to GitHub.

default

default

xerta555 commented 6 years ago

I only saw a blank page, and did not see the TypeError. Have you uploaded the code to this repo?

Hello, thanks for answer. I just have upload directly my Actions.html, Actions.js and Actions.css files with the background img on the repo.

And thank you about the hability to push directly my changes from VS to my git :+1: Edit: Apparently, i must to login to an MS account to be able to login to my git account, right ?

I want to know how to adding a new text link to a local html file, i tried to changing the data-tip-position and the class properties to display the link on the background image but nothing works. Maybe that i must changing some properties of the div ?

jingyu9575 commented 6 years ago

i must to login to an MS account to be able to login to my git account

No, Team Explorer only asks for the GitHub account to push the changes. The Community (Free) edition of Visual Studio requires Microsoft account though.


TypeError: document.querySelector(...) is null

In the JS file, this line is a CSS rule (the spaces inside background-image are probably inserted by the code formatter). It is not valid JS and causes syntax error.

There are many syntax errors in the HTML file.

data-tip-position is not an attribute for the browser, but an attribute for use in JS. For example, uBlock Origin has code to use it. You have not written any JS code to use this attribute, so it has no effect.

class is used in CSS selectors, or JS code such as document.querySelector('.my-class-name'). Again, it has no effect if no CSS or JS code is using it.

I still suggest rewriting the HTML file, without the parts from other extensions.


For a quick introduction to the HTML syntax and structure, see this tutorial. Basically, HTML consists of tags. For example:

<p>My first paragraph.</p>

<p> is the start tag, and </p> is the end tag. Things between them is tag's content, which can include text and/or other tags. Each tag means a type of element e.g. the p tag means a paragraph.

Attribtes are written in the start tag, and provide additional information for the tags. The browsers use attributes such as id, class for any tags, and use some other attributes for specific tags e.g. href in a tag. Other attributes, aside from the list used by the browser, have no effect by default. For example:

<a href="About.html">My link</a>

This a tag represents a link, and the href attribute provides the link's target. If you use href in p tag, it will have no effect.

Tags can contain other tags:

<p>
    <a href="1.html">First link</a>
    <a href="2.html">Second link</a>
</p>

This is a paragraph, which has two links. Whitespaces and newlines are equivalent, and the links may show horizontally.

Some tags only use start tag without end tag, such as <img>.


The basic structure of a HTML file is:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

</body>
</html>

Except the doctype, everything is in a <html> tag (note the end tag </html> at the bottom). Inside <html>, there is a <head> tag and a <body> tag. The <head> tag contains meta information such as the encoding and the title, while the <body> tag contains the page content.

I suggest starting from this minimal file, including the JS and CSS with <script> and <link> tag, and adding necessary tags for your content. Don't add unused tags and attributes that have no effects.

xerta555 commented 6 years ago

@jingyu9575 Hello again, I've been trying for several hours to understand how html, css and js files work with Firefox but i'm currently completely lost.

You gave me a lot of information, and i thank u again for that but i don't understand at all how to use these languages for an interaction with Firefox, especially the HTML tags.

I try to help myself from sources of other modules except that each time different display and coding methods are used, which loses me even more.

I basically understood how base tags like div, span work, but in my case, i don't understand how to create a text link that will appear in my popup in Firefox.

I also don't understand much about the step-by-step operation of this part there (i can guess, but since the JS language sounds particularly raw to understand...).

The CSS part is the part i understand the most easily (maybe it's also the simplest part, only you will be able to say yes or no).

Overall, and especially in my case, i don't understand how i will be able to tell Firefox to display a link to a local HTML file (Options.html) using split tags, span, and others via the data-i18n API.

I must be very boring on this subject, but knowing me, it's the beginning that is the hardest :)

Maybe that u have already answer me on several points, sorry in advance.

xerta555 commented 6 years ago

My actual Actions.js file: js

My actual Actions.html file: html

And my Action.css file: css

I haven't push my changes on my git because i don't know if i will must write again all my files.....

jingyu9575 commented 6 years ago

Think HTML tags as a way to mark text. For example:

Mozilla Firefox is a web browser.
It is developed by Mozilla Foundation.

This is a simple plain text, without any formatting or different elements. You can use the Tryit Editor to see the result. Copy this text to the left box and click "Run", and you will see the text is shown directly without any effects.

Now I want to mark the first two words "Mozilla Firefox" as bold. In modern document editors I can just select them and click the "B" icon, but in HTML everything must be written as code. Therefore people invented a way to mark the text: putting <b> before them, and putting </b> after them, so the code becomes:

<b>Mozilla Firefox</b> is a web browser.
It is developed by Mozilla Foundation.

Update the code in the Tryit Editor to see the effect.

Next, I want to change "Mozilla Foundation" to a link to mozilla.org. Similarly, people invented a tag <a> for that:

<b>Mozilla Firefox</b> is a web browser.
It is developed by <a>Mozilla Foundation</a>.

However, this does not have any effect yet, because the browser does not know the link's address. Therefore, people came up with attributes, and invented an attribute called "href" to represent the address.

<b>Mozilla Firefox</b> is a web browser.
It is developed by <a href="https://www.mozilla.org">Mozilla Foundation</a>.

Next, I want to add a the Firefox logo at the beginning. There is a tag <img> for that, and the image's address is represented by the "src" attribute. Because images do not contain any text, the <img> tag should be empty and has no end tag (no </img>).

<img src="https://www.mozilla.org/media/img/firefox/favicon.e6bb0e59df3d.ico">
<b>Mozilla Firefox</b> is a web browser.
It is developed by <a href="https://www.mozilla.org">Mozilla Foundation</a>.

Finally, I can add a title with the <h1> tag:

<h1>Firefox</h1>
<img src="https://www.mozilla.org/media/img/firefox/favicon.e6bb0e59df3d.ico">
<b>Mozilla Firefox</b> is a web browser.
It is developed by <a href="https://www.mozilla.org">Mozilla Foundation</a>.

We see that HTML tags are just a way to mark text. These days we have CSS, a powerful tool for layout and styling, so some tags for styling such as <b> are less used. However, to display a link, <a> is still commonly used.

The tags <div> and <span> have no meaning (semantics) or style. They are used to mark text for use in CSS or JS.

I suggest reading a HTML tutorial such as this, to get familiar with the commonly used tags and attributes.

xerta555 commented 6 years ago

@jingyu9575 Hello, i don't know how to parse my string message from a manifest.json file as hypertext link, there is my actual attempt:

img

I attach my Actions.html file if needed. Actions.zip

Can u say me what i make wrong ?

EDIT

I have finally fix them, but now i get: SyntaxError: JSON.parse: unterminated string at line 18 column 19 of the JSON data It come from that special carachters like "é" "è", how fix that ?

EDIT 2

Fixed, the locales messages.json must to be formated in UTF-8, now loaded and correctly displayed in the Firefox popup.

xerta555 commented 6 years ago

@jingyu9575

To download the images, the background script must access the http://feed.500px.com/500px-best website. canvas.toDataURL does not work here (it is for getting image data from a canvas element). You can use the fetch API or XMLHttpRequest to access the website. Extract the image URLs, fetch again to get the image content, and then you can put it to the storage.

Hello, i'm currently looking into API u suggested to me in your first answer.

Apparently, regarding in the compatibility section of Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API#Browser_compatibility, i think that the basic and signal support of ths API aren't enough.

About XMLHttpRequest API seems sufficiently implemented to be used in my addon, i will just have to be careful about the values in the responses obtained because as explained, some forms of responses may vary depending on the version of Firefox used.

I don't really have any ideas on how i should start writing at javascript level, but internet is also made for it. As i have now understood how HTML and CSS work thanks to the current practice, i suppose it will be the same with javascript. Multiple examples and Q/A that i could read on the net, this throwing seems to be quite speaking.

Concerning your suggestion to store images in a database file (IndexedDB) with a unit identification by key, i think that the first API you mentioned (browser.storage) might be the easiest to start with?

As for the API that i will use in Firefox, either chrome_url_overrides (which i currently use or theme_ntp_background which is still under development and apparently intended to be implemented in Firefox 63 (you confirm? https://bugzilla.mozilla.org/show_bug.cgi?id=1347204).

I think i should start with the first one, chrome_url_overrides, then see over time if the future theme_ntp_background API will only change the background image and why not also some properties applicable to some objects like transparency for example?

jingyu9575 commented 6 years ago

Fetch API

The link shows that Fetch API is compatible with Firefox 39+, and the signal feature (ability to abort requests) is compatible with Firefox 57+. I think it is enough for the extension. (What version do you plan to support?)

"Streaming response body" means downloading large files progressively and getting partial data. For small files that can be downloaded completely, this feature is not required. I've considered using this API in multithreaded-download-manager instead of StreamFilter which is related to the high CPU usage, but it is not officially supported now (requires an about:config change) and has some crash problems.

In my opinion, Fetch is easier to use than the old XMLHttpRequest API. Of course XMLHttpRequest is also supported in modern browsers and can also be used.

browser.storage might be the easiest to start with

Yes, I think browser.storage is easier than IndexedDB.

theme_ntp_background bugzilla.mozilla.org/show_bug.cgi?id=1347204

The link is for the New Tab Page colors. This is the tracking bug of theme_ntp_background, and there is no recent activity.

I think i should start with the first one, chrome_url_overrides, then see over time if the future theme_ntp_background API...

I agree.


There is a syntax error in Actions.html (this line). The browser can recover from it but the result is not correct. In this case, the error does not affect other tags, so you may not see any effects, but I suggest avoiding syntax errors in general. default

xerta555 commented 6 years ago

The link shows that Fetch API is compatible with Firefox 39+, and the signal feature (ability to abort requests) is compatible with Firefox 57+. I think it is enough for the extension. (What version do you plan to support?)

Actually i don't know precisely wich version i will set for the strict_min_version property, for now i have set the 57 but i think that i will evolve.

"Streaming response body" means downloading large files progressively and getting partial data. For small files that can be downloaded completely, this feature is not required. I've considered using this API in multithreaded-download-manager instead of StreamFilter which is related to the high CPU usage, but it is not officially supported now (requires an about:config change) and has some crash problems.

Another problem i'm gonna face so if i understand you correctly?

In my opinion, Fetch is easier to use than the old XMLHttpRequest API. Of course XMLHttpRequest is also supported in modern browsers and can also be used.

So if Fetch is easier to take again your words, i should more use it instead of XMLHttpRequest, but do they have overall the same potential for what i would like to do in my extension or are there still doubts at that level?

The link is for the New Tab Page colors. This is the tracking bug of theme_ntp_background, and there is no recent activity.

Question a little useless but I'm going to ask you: do you think that its implementation will one day be officialized as WebExtension or is it unlikely?

There is a syntax error in Actions.html (this line). The browser can recover from it but the result is not correct. In this case, the error does not affect other tags, so you may not see any effects, but I suggest avoiding syntax errors in general.

Thank u. I'm getting to pull the fix, a fix for my manifest.json file and my Options html and css pages too.

Feeling a lot more comfortable with the HTML and CSS with my practise, i'm looking on how the JS language work, i will make the About.html and it's css file more later. I will write in them the known bugs and the API i have used so it's not important for now.

A last thing: u could find some strange things on my part and various errors probably not impacting the general rendering, i encountered some difficulties and rewrite some parts of the HTML code to make it work as i wanted, but i managed to get the result i wanted.

I'm currently looking on my Options.js file to make the div for the special permission section that i want to make diseappared if browserSettings permission is allow for my addon.

xerta555 commented 6 years ago

@jingyu9575 Also, i don't arrive to hide my local-file div on page load (so by default) until the user haven't got select the local_update option in my select menu.

I'm currently trying by this method:

My html:

option

The area to hide by default:

area

And there is my actual js attempt:

js

I have take my attempt from this thread: https://stackoverflow.com/questions/16712941/display-div-if-a-specific-select-option-value-is-selected But strangly, it make the local_update option by default on page loading, so in some words the opposite of what i want to do, and even by inverting the perperty value in the three scenarios the result is the same for me even by Update the addon in the about:debugging FF page.

Would you have an idea on what i made wrong please ?

jingyu9575 commented 6 years ago

do they have overall the same potential for what i would like to do in my extension or are there still doubts at that level

I think "Basic support" of the fetch API is enough for the extension (loading the 500px web page and downloading images). There is no need for the "Streaming response body" feature.

do you think that its implementation will one day be officialized as WebExtension or is it unlikely

I guess it is likely to be officialized. The assignee Tim Nguyen is a very active developer of WebExtensions themes.

default


hide my local-file div on page load (so by default) until the user haven't got select the local_update option in my select menu.

The code first gets a specific <option>'s value (document.getElementById("admOption").value) and puts it into the variable admOptionValue. Then admOptionValue is compared with the selected value. If the values are equal, it adds a CSS rule display: none to your div to hide it.

You want to test the local_update option here (comparing its value with the selected value), so you want the code document.getElementById("admOption") to get the local_update option element, but the id is wrong. See your stackoverflow link: the third option has an id in the HTML, which matchs the id here.

Another problem is that all your options have the same value, so the method of comparing the values does not work. Change the values to be distinct (they do not need to be numbers).

One of the "local-file" id strings contains spaces, which is not allowed. Visual Studio sometimes adds spaces when you paste code outside quotes to improve readability, so fix them or paste them inside the quotes.


admOptionValue = document.getElementById("admOption").value;

This line creates a new variable, but it lacks the var, let or const keyword. Without the keyword, the statement will fail in strict mode or create a global variable in non-strict mode.

xerta555 commented 6 years ago

I think "Basic support" of the fetch API is enough for the extension (loading the 500px web page and downloading images). There is no need for the "Streaming response body" feature.

OK i will take a look after i will finishing my settings page.

I guess it is likely to be officialized. The assignee Tim Nguyen is a very active developer of WebExtensions themes.

Great, it's could be nice !

The code first gets a specific

You want to test the local_update option here (comparing its value with the selected value), so you want the code document.getElementById("admOption") to get the local_update option element, but the id is wrong. See your stackoverflow link: the third option has an id in the HTML, which matchs the id here.

Understood, so i have edit my html like that: menu

local

And my js script like that: js

But it don't work

One of the "local-file" id strings contains spaces, which is not allowed. Visual Studio sometimes adds spaces when you paste code outside quotes to improve readability, so fix them or paste them inside the quotes.

I have read all my id strings inside the admDivCheck and there is no id that contain a space..

This line creates a new variable, but it lacks the var, let or const keyword. Without the keyword, the statement will fail in strict mode or create a global variable in non-strict mode.

Do u say that even if all my id values and js script is good, the result will never happen because the answer at: https://stackoverflow.com/questions/16712941/display-div-if-a-specific-select-option-value-is-selected is wrong ?

jingyu9575 commented 6 years ago

no id that contain a space

I meant this line: default

it don't work

The JS code should be inside function admSelectCheck(nameSelect) { }. In the HTML, the <select> has onchange="admSelectCheck(this);". This means whenever the dropdown is changed by the user, call the admSelectCheck function, and pass the element as the argument (which becomes nameSelect in the function).

If it still does not work, please upload the code so I can download and test.

the answer at ... is wrong

It will work in non-strict mode. If you don't use those keywords, the line admOptionValue = ... creates a global variable admOptionValue. Global variables work across functions. If another function happens to use a global variable called admOptionValue, it will be affected by this assignment, causing unexpected behavior.

Strict mode JS bans this way to create global variables, making this code to throw errors.

It is recommended to create local variables instead, by using one of var, let and const keywords:

let admOptionValue = document.getElementById("admOption").value;

This way, the variable only exists locally, so if another function happens to use the same name, it will not be affected.

xerta555 commented 6 years ago

If it still does not work, please upload the code so I can download and test.

I just have upload my last changes on my git, thanks to tell me what's wrong in my file(s).

xerta555 commented 6 years ago

@jingyu9575 Hello, i have recently tried to add the option in my settings menu to let to the user the choice to opening the options page in a newtab page or not by following your changes in your Add option showOptionsInDedicatedTab (final-ready files). I get my translated string and the checkbox for the user-choice, but when i test to see if it works, it don't and i get theses error message in FF console:

TypeError: chromeWin.gBrowserInit is undefined ext-webNavigation.js:128:1 TypeError: Settings.get is not a function Options.js:11:1 TypeError: chromeWin.gBrowserInit is undefined ext-webNavigation.js:128:1

I don't understand this error because i have write the links of my js files in my html ones.

I just have commit all my last changes on the repo, i have a question: (i think that the answer will yes but i'm nnot sure, i let u confirm) There is my About.html page in FF: about-page

There is possible to add some html elements at right of the vertical separator (vl element), where my pointer is ? If it's possible, i don't think that there are special html snippet(s) to use for that (fix me if i'm wrong).

Also tomorrow i will fix my options page, because since i implement the option page in newtab feature, i have see that some elements aren't optimized for a good reading.

EDIT: Alternativly, when u will see my error(s) for the new option in my settings page, i want to edit dynamicaly CSS properties by js or css (if possible). For exemple: => When the checkbox for displaying the Options page in a new tab is enabled, comment a css value like: margin for div#settings-intro, section > div for @media screen and (max-width: 900px).

=> When the checkbox for displaying the Options page in a new tab is enabled, uncomment a css value like: margin for div#settings-intro, section > div for @media screen and (max-width: 900px).

jingyu9575 commented 6 years ago

My extension uses a complicated Settings class to manage all the settings, which uses the storage.local API. In TypeScript, this class provides auto completion for the name of the settings, but since you use JavaScript, there is no advantage of this class and you can just use storage.local directly.

TypeError: Settings.get is not a function Options.js:11:1

This error is because you are using the Settings class but have not included its source, in the link above. Instead of using this class:

await Settings.get('showOptionsInDedicatedTab')

you can just use storage.local.get:

(await browser.storage.local.get()).showOptionsInDedicatedTab

The other two errors are in Firefox's internal file "ext-webNavigation.js" and not related to the extension.


I'd modify "Popup.js" to:

document.querySelector('#clickSettings').addEventListener('click', async (event) => {
    event.preventDefault();
    if ((await browser.storage.local.get()).showOptionsInDedicatedTab)
        void browser.tabs.create({ url: browser.runtime.getURL('/html/Options.html') });
    else
        void browser.runtime.openOptionsPage();
});

The id of the link and the options page URL are different in your extension. Also, the default action of the link (opening href) should be suppressed, so event.preventDefault(); is put here.

In addition, this showOptionsInDedicatedTab setting should be updated when the checkbox is toggled. In my extension there is lots of code in the options page to deal with that, but I think you can just start with a click event for the checkbox.


If it's possible, i don't think that there are special html snippet(s) to use for that

You are right. The layout should be written in the CSS.

In your existing CSS:

So one of the approaches is to add another div with position: absolute, top: 0 and (for example) left: 52%. However I think it is very difficult to put everything in the correct place with these hardcoded distances and percentages. For this one-dimension layout problem, I'd use flexbox in modern browsers.

jingyu9575 commented 6 years ago

For clarity, let's use the following simplified HTML as an example :

<div id="container">
    <div id="left-pane">Left pane</div>
    <div id="separator"></div>
    <div id="right-pane">Right pane</div>
</div>

and the desired layout is:

[        left-pane        ] [separator] [        right-pane       ]

First, set display: flex on the container to use flexbox. We see that:

That's it:

#container {
    display: flex;
    flex-direction: row;
}
#left-pane, #right-pane {
    flex: 1;
}
#separator {
    background-color: blue;
    width: 6px;
}

See the result in the TryIt Editor (click "Run").

xerta555 commented 6 years ago

Thanks a lot for your infos.

I have edit Popup.js but the result don't happen.. I don't know where is/are my error(s).

You are right. The layout should be written in the CSS.

I have following your exemple, i'm arrived to make my ids texts area to be moved on the middle of my page, but not the git img, also here idk there is/are my error(s).

What's weird is that i followed your model by replacing my container, my ids and my divs' names, but it almost didn't work properly.

I have push all my changed files on the repo to check it..

jingyu9575 commented 6 years ago

I have edit Popup.js but the result don't happen..

Did you include this file in Actions.html?

i'm arrived to make my ids texts area to be moved on the middle of my page, but not the git img

First check the syntax. CSS can be written in the CSS file or in <style> tags in the HTML file, but the latter is not recommended because it mixes CSS and HTML, so I suggest remove the style tags in the HTML file. In the CSS file, remove unrelated HTML tags.

With your ids, the CSS should be:

#container {
    display: flex;
    flex-direction: row;
}

#about-mdn, #about-dev {
    flex: 1;
}

.vl {
    background-color: blue;
    width: 6px;
}
xerta555 commented 6 years ago

Did you include this file in Actions.html?

Heu, i don't understand why i should include: <script src="/js/Popup.js"></script> in Actions.html file ?

First check the syntax. CSS can be written in the CSS file or in