Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Jordan Gwyn
@emanresusername
@lucidd cool thanks ! I see the minimal one with tab println, Is there anything a little more involved?
In particular I wanted to open a window and then render some stuff to it from the background window?
Kevin Walter
@lucidd
@emanresusername i think your best bet is to find an open source extension that does similar things to what you want to do and see what apis they are using. You can always take a look at https://developer.chrome.com/extensions/api_index and https://developer.chrome.com/apps/api_index so see whats available for apps and extensions. One thing to note is that apps and extensions dont share all the apis some are exclusive to one or the other.
in your case only apps have access to the this api https://developer.chrome.com/apps/app_window extensions can only mess with normal chrome windows/tabs
Jordan Gwyn
@emanresusername
Ahh gotcha. Yeah I'd been sorta starting to do that but it was pretty slow-going and it's not my expertise :(
I think maybe what could work for me is if all the scripts that come with that Chrome.defaultScripts manifest option in the background page could be applied to a foreground one? If that makes sense? (Sorry I'm just getting my feet wet here and not super well versed in all the right terminology)
@lucidd
Kevin Walter
@lucidd
i'm not an expert either but maybe if you tell me what you are trying to do i can point you to something
Jordan Gwyn
@emanresusername
@lucidd :+1: , basically just trying to port this extension to scala js and use this framework
Jordan Gwyn
@emanresusername
actually i think i’ve got it mostly figured out now, i think the only thing i need now is how to bind a listener to the when the browserAction button is clicked?
Jordan Gwyn
@emanresusername
import scala.scalajs.js
import scala.scalajs.js.annotation.JSName
import chrome.events.bindings.Event
import chrome.tabs.bindings.Tab

@js.native
@JSName("chrome.browserAction")
object BrowserAction extends js.Object {

  val onClicked: Event[js.Function1[Tab, _]] = js.native
}
this seemed to work for me, but not sure if this is a good way to do it? glad to submit a PR if this is of value to the core project?
Jordan Gwyn
@emanresusername
ok, i’ve got something concrete now. the storage issue i was talking about before, you can see in this branch of the web extension. found work arounds to the other issues
Kevin Walter
@lucidd
@emanresusername the onClicked mapping looks correct if you want to make a PR for that i would accept it.
i will see if i can reproduce the storage problem with your branch.
Jordan Gwyn
@emanresusername
:+1:
Kevin Walter
@lucidd
@emanresusername i can't really reproduce your error but i realize now that the storage bindings are pretty awful to work with in its current form
Jordan Gwyn
@emanresusername
haha, didn’t want to be that guy complaining without any solution to offer, but yeah those were a little rough to work with :sweat_smile:
any way it could take just String keys for get?
Kevin Walter
@lucidd
ah now i could reproduce the error seems like you only get those checks in fast mode not in opt mode
i will try to adjust the bindings a bit and see if i can fix it and make it a bit nicer on the scala side
Jordan Gwyn
@emanresusername
thanks! :+1:
Kevin Walter
@lucidd
@emanresusername i think i got something working here https://github.com/lucidd/scala-js-chrome/tree/storage-fix
with that the bindings are usable like this
chrome.storage.Storage.local.set(Map("hello" -> "world")).foreach(println)
chrome.storage.Storage.local.get(Array("hello")).foreach(println)
Jordan Gwyn
@emanresusername
sweet! on the clock for a while, but will check it out soon as i get off!
Jordan Gwyn
@emanresusername
@lucidd got a little (lot :sweat_smile: ) derailed today. Huge :+1: on the niceness improvement on the method signatures!
and not seeing the same error in the console any (which could easily mean i was just doing something wrong to begin with :) )
kramer425
@kramer425
Hi everyone, I just found this project last week and it looks great. I set up the sample extension (slightly modified), but I can only get it to work with sbt-chrome-plugin v 0.2.1, as well as scala 11.8. Would you guys mind taking a look at my build.sbt?
Kevin Walter
@lucidd
Hey, sure if you post a link to your project I can take a look later
kramer425
@kramer425
Thanks so much Kevin, it's here: https://github.com/kramer425/SN
Kevin Walter
@lucidd
@kramer425 something like this should work
 import chrome._
import chrome.permissions.Permission
import chrome.permissions.Permission.API
import net.lullabyte.{Chrome, ChromeSbtPlugin}

lazy val root = project.in(file("."))
  .enablePlugins(ChromeSbtPlugin)
  .settings(
    name := "sn",
    version := "0.1.0",
    scalaVersion := "2.11.8",
    scalacOptions ++= Seq(
      "-language:implicitConversions",
      "-language:existentials",
      "-Xlint",
      "-deprecation",
      "-Xfatal-warnings",
      "-feature"
    ),
    persistLauncher := true,
    persistLauncher in Test := false,
    relativeSourceMaps := true,
    libraryDependencies ++= Seq(
      "net.lullabyte" %%% "scala-js-chrome" % "0.4.0" withSources() withJavadoc(),
      "com.github.japgolly.scalajs-react" %%% "core" % "0.11.3" withSources() withJavadoc(),
      "com.github.japgolly.scalajs-react" %%% "extra" % "0.11.3" withSources() withJavadoc()
    ),
    jsDependencies += "org.webjars" % "react" % "0.13.3" / "react-with-addons.min.js" commonJSName "React",
    skip in packageJSDependencies := false,
    chromeManifest := new ExtensionManifest {
      val background = Background(
        scripts = Chrome.defaultScripts
      )
      val name = Keys.name.value
      val version = Keys.version.value
      override val permissions = Set[Permission](
        API.Tabs,
        API.Management
      )
    }
  )
kramer425
@kramer425
That did it Kevin! When I previously tried to import chrome.permissions.Permission, intellij said it couldn't find it, but it's working now so that's great. Thanks so much for your help
kramer425
@kramer425
Hey guys, are content scripts the only way for an extension to modify the dom of a given tab's page?
kramer425
@kramer425
I think I answered my own question. Are content scripts on the todo for this library?
Kevin Walter
@lucidd
@kramer425 there are no direct plans for special content script support but i think the API for injecting them should already be available. You could also try to inject your extension script as content script and have some detection at the beginning if you are running as extension or as content script and execute code accordingly.
@kramer425 if you have any idea of what special content script support would look like feel free to open an issue for discussion :smile:
Jordan Gwyn
@emanresusername
@lucidd the scalajs sbt settings (really just the build.sbt in general :sweat_smile: ) are like a foreign language to me. do you know off the top of your head or have pointers for how to make this work with the scala-js-bundler plugin?
Kevin Walter
@lucidd
@emanresusername haha yeah sbt takes a little to get used to :smile: i have not used this plugin yet but https://scalacenter.github.io/scalajs-bundler/getting-started.html seems to be a good start. There is also a link to a full example project at the bottom. Hope it helps
Jordan Gwyn
@emanresusername
I'll try to make a minimal project combining the two and see if I can nail down exactly what the conflict is
Jordan Gwyn
@emanresusername
@lucidd so for something like this
my intuition would be to run like bundlerExtension/chromeUnpackedFast::webpack and then be able to load the directory in target/chrome/unpacked-fast as an unpacked extension as expected, but there are clearly some more configuring i need to do to make that work. Does that make more sense/help clarify?
kramer425
@kramer425
@lucidd Hi Kevin, I just asked in the scala-js chat about splitting code into multiple js files. I would need another project in my build in order to do that. Since content scripts are not allowed to access any of the chrome apis, does it make more sense to keep content script creation out of the scala-js-chrome project?
Although, I would need to be able to access the messaging api
Kevin Walter
@lucidd
I think this is a similar problem to projects that have a Scala server project which needs a scalajs client project as a ressource.
@kramer425 you should be able to have two projects in sbt and use the generated Resource mechanism to copy content script into the extension. Depending on this library in your content script should not be a problem as long as you dont use anything thats not availabe in the web page. scalajs will make sure to only include what you actually use so there should be no additional cost.
kramer425
@kramer425
Thanks Kevin I'll try that. Since I can specify which websites I want the content script to run on, do you think I would include a main in it as well?
Kevin Walter
@lucidd
i think it needs a main to run if you inject it into the website but you have to look at the content script documentation
kramer425
@kramer425
Ok thanks. Do you think in CodeInjectionOptions def apply(code: js.UndefOr[String] = js.undefined, could be changed to take a js.Any or js.Function so you can pass in scala code?
Kevin Walter
@lucidd
@kramer425 that would be cool but i don't think thats possible. Chrome wants a string of javascript there is no way around that. maybe it would be possible to use a macro to pass in a scala function and have it at compile time transformed into a string of javascript but i don't think its trivial.
Simone Robutti
@chobeat

Hello, I'm a scalajs newb (and not really skilled in JS either). I'm trying to create a chrome extension using scala-js-chrome

I got a general idea on how to work with the ChromeApp API and how to create windows but I would like to actually create an extension that listens to events in all the tabs. I saw how to do this in JS through CodeInjection. My problem is that, while the wrapper wraps the corresponding call "executeScript", I don't know how to pass the actual code to execute. The options available are through a string and through a filename. ( https://github.com/lucidd/scala-js-chrome/blob/master/bindings/src/main/scala/chrome/tabs/bindings/CodeInjectionOptions.scala )

In my newbiness I have no idea how to do so through scalajs

Kevin Walter
@lucidd
@chobeat there are multiple ways you could go about this. Chrome wants either javascript as a string or a file to inject. You could just inject a plain javascript file if you want but i guess thats not what you are looking for. Alternatively you could inject your extension script itself and have some check in the main for if its running in a web page or as extension and act accordingly. The third option is to setup a multiproject sbt build where you have your extension project and your inject script project and have the extension depend on the output of the inject script project as a resource.
Simone Robutti
@chobeat
@lucidd thank you very much. I'm not sure about how to go for the second option but I will try something. Otherwise the third option seems the cleanest and I will go for it
kramer425
@kramer425
@chobeat If you get the third option to work, please let me know!
@lucidd Thanks Kevin, didn't see your last response. Hopefully Simone makes progress with using multiprojects to write content scripts in scala