SlideShare a Scribd company logo
Writing Browser Extensions in Kotlin
Kirill Rakhman (@Cypressious)
busradar.com
KotlinJS
● No longer expiremental since 1.1.0
● Can run anywhere where JS runs
○ Websites
○ NodeJS
○ Browser Extensions
● Can call JS
○ the dynamic way
○ the static way
● Benefits from all IDE features you know from Kotlin on the JVM
● Question: Does it make writing browser extensions more pleasant?
About dynamic
val a: Any = js("{}")
a.foo()
val b: dynamic = a.asDynamic()
b.foo()
b["baz"] = "qux"
Calling external code
external val foo: dynamic
external class External {
fun callMe()
}
fun main() {
foo.bar()
foo.baz.qux = false
val e = External()
e.callMe()
e.somethingElse()
}
WebExtensions
● A new cross-browser extension API standard
● Implemented by Firefox, Chrome, Opera and Edge to varying degrees
● We’re going to focus on Firefox
Calling the WebExtensions API from Kotlin
● external val browser: dynamic
○ easily implemented
○ no compile-time safety
○ no IDE support
● writing external declarations
○ extra effort
○ compile-time safety (assuming you wrote the declarations correctly)
○ IDE support
● code generation from schema
○ no extra effort (because I did it ;)
○ compile-time safety guaranteed by official schema
○ awesome IDE support, including autocompletion, KDoc, deprecation, ...
The schema
{
"name": "sendMessage",
"type": "function",
"description": "...",
"async": "responseCallback",
"parameters": [
...,
{
"type": "object",
"name": "options",
"properties": {
"frameId": {
"type": "integer",
"optional": true,
"minimum": 0,
}
},
"optional": true
}
]
}
API Structure
browser
Namespace
Namespace
Namespace
Event
Event
Event
Function
Function
Function
Type
Type
Type
$ref
Transforming JS objects
"parameters": [
{
"type": "object",
"name": "createProperties",
"properties": {
"windowId": {
"type": "integer",
"optional": true
},
"url": {
"type": "string",
"optional": true
},
"active": {
"type": "boolean",
"optional": true
}
}
]
class CreateProperties(
var windowId: Int? = null,
var url: String? = null,
var active: Boolean? = null
)
Transforming JS objects (alternative)
"parameters": [
{
"type": "object",
"name": "createProperties",
"properties": {
"windowId": {
"type": "integer",
"optional": true
},
"url": {
"type": "string",
"optional": true
},
"active": {
"type": "boolean",
"optional": true
}
}
]
external interface CreateProperties {
var windowId: Int?
var url: String?
var active: Boolean?
}
fun CreateProperties(
windowId: Int? = null,
url: String? = null,
active: Boolean? = null
) : CreateProperties {
val o: dynamic = js("{}")
o.windowId = windowId
o.url = url
o.active = active
return o
}
https://youtrack.jetbrains.com/issue/KT-21653
Transforming Map-like objects
"formData": {
"type": "object",
"properties": {},
"additionalProperties": {
"type": "array",
"items": { "type": "string" }
}
}
{
"type": "object",
"patternProperties": {
"^[1-9]d*$": {"$ref": "ImageDataType"}
}
}
class FormData {
inline operator fun get(key: String):
Array<String> = asDynamic()[key]
inline operator fun set(key: String,
value: Array<String>) {
asDynamic()[key] = value
}
}
Transforming union types in function parameters
"functions": [
{
"name": "get",
"type": "function",
"async": "callback",
"parameters": [
{
"name": "idOrIdList",
"choices": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
...
external class BookmarksNamespace {
fun get(idOrIdList: String):
Promise<Array<BookmarkTreeNode>>
fun get(idOrIdList: Array<String>):
Promise<Array<BookmarkTreeNode>>
}
Transforming union types
{
"id": "OnClickData",
"type": "object",
"properties": {
"menuItemId": {
"choices": [
{ "type": "integer" },
{ "type": "string" }
]
},
...
class OnClickData(
var menuItemId: MenuItemId
)
typealias MenuItemId = Any
:(
Transforming Events
"events": [
{
"name": "onCreated",
"type": "function",
"parameters": [
{
"$ref": "Tab",
"name": "tab"
}
]
},
...
external class Event<in T> {
fun addListener(listener: T)
fun removeListener(listener: T)
fun hasListener(listener: T): Boolean
}
val onCreated: Event<(tab: Tab) -> Unit>
Generating Code
● KotlinPoet is “a Kotlin and Java API for generating .kt source files.”
● Heavy use of the Builder pattern
● Make use of information like optional parameters, deprecation, KDoc, ...
private fun generateFunction(f: Function, parameters: List<Parameter>): FunSpec {
val builder = FunSpec.builder(f.
name)
f.description?.let { builder.addKdoc(
it + "n") }
parameters.forEach {
builder.addParameter(generateParameter(
it.name!!, it).build())
}
f.deprecated?.let {
builder.addAnnotation(AnnotationSpec.builder(
Deprecated::class).addMember(""$it"").build())
}
returnType(f)?.
let { builder.returns(
it) }
return builder.build()
}
The generated code
external val browser: Browser
external class Browser {
val tabs: TabsNamespace
...
}
external class TabsNamespace {
/** ... */
fun move(tabIds: Int, moveProperties: MoveProperties): Promise<Tabs2>
/** ... */
fun move(tabIds: Array<Int>, moveProperties: MoveProperties): Promise<Tabs2>
...
}
class MoveProperties(...)
https://github.com/cypressious/kotlin-webextensions-declarations
Code Demo
Future improvements
● Tooling
○ Multiple projects for different output files are annoying
● Keeping up with API updates
○ Auto generate using Gradle plugin?
● Use external interfaces instead of classes
○ Smaller compiled JS
● Make it compatible with Chrome
○ Is not Promise based
○ Base object
○ Polyfill¹ already exist
¹ https://github.com/mozilla/webextension-polyfill
Thank you for your
attention Kirill Rakhman
cypressious
rakhman.info
Writing the plugin
buildscript {
ext.kotlin_version = '1.2.70'
repositories {
mavenCentral()
}
dependencies {
classpath
"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
version '0.1'
https://github.com/cypressious/webextension-search-kotlin-docs
allprojects {
apply plugin: 'kotlin2js'
apply plugin: 'kotlin-dce-js'
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
compile
"org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
compile
'com.github.cypressious.kotlin-webextensions-declarations:w
ebextensions-declarations:v0.1'
}
compileKotlin2Js {
kotlinOptions.sourceMap = true
kotlinOptions.sourceMapEmbedSources = "always"
}
}
Writing the plugin
{
"description": "Adds a context menu item to search for the selected word in the Kotlin documentation",
"manifest_version": 2,
"name": "Search Kotlin",
"version": "1.0",
"icons": {
},
"background": {
"scripts": [
"build/kotlin-js-min/main/kotlin.js",
"build/kotlin-js-min/main/declarations.js",
"build/kotlin-js-min/main/ff-search-kotlin.js"
]
},
"permissions": [
"menus"
]
}
https://github.com/cypressious/webextension-search-kotlin-docs
Writing the plugin
import menus.CreateProperties
import webextensions.
browser
fun main(args: Array<String>) {
browser.menus.create(CreateProperties(
id = "search-kotlin",
title = "Search in Kotlin Docs",
contexts = arrayOf("selection")
))
browser.menus.onClicked.addListener { info, tab ->
when (info.menuItemId) {
"search-kotlin" -> {
browser.tabs.create(tabs.CreateProperties(
url = "http://kotlinlang.org/?q=${info.selectionText}&p=0"
))
}
}
}
}
https://github.com/cypressious/webextension-search-kotlin-docs
Writing browser extensions_in_kotlin

More Related Content

What's hot

The Ring programming language version 1.4 book - Part 12 of 30
The Ring programming language version 1.4 book - Part 12 of 30The Ring programming language version 1.4 book - Part 12 of 30
The Ring programming language version 1.4 book - Part 12 of 30
Mahmoud Samir Fayed
 
Windows ストアーアプリで SQLite を使ってみよう
Windows ストアーアプリで SQLite を使ってみようWindows ストアーアプリで SQLite を使ってみよう
Windows ストアーアプリで SQLite を使ってみよう
ShinichiAoyagi
 
D3.js and SVG
D3.js and SVGD3.js and SVG
D3.js and SVG
Karol Depka Pradzinski
 
The Ring programming language version 1.5.4 book - Part 43 of 185
The Ring programming language version 1.5.4 book - Part 43 of 185The Ring programming language version 1.5.4 book - Part 43 of 185
The Ring programming language version 1.5.4 book - Part 43 of 185
Mahmoud Samir Fayed
 
How dojo works
How dojo worksHow dojo works
How dojo works
Amit Tyagi
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 
Design Patterns in Go Code
Design Patterns in Go CodeDesign Patterns in Go Code
Design Patterns in Go Code
Kamil Mówiński
 
Coffee script
Coffee scriptCoffee script
Coffee script
Jordan Dichev
 
Intorduction of Playframework
Intorduction of PlayframeworkIntorduction of Playframework
Intorduction of Playframework
maltiyadav
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
Ali Parmaksiz
 
jQuery Learning
jQuery LearningjQuery Learning
jQuery Learning
Uzair Ali
 
Extjs + Gears
Extjs + GearsExtjs + Gears
Extjs + Gears
hagino 3000
 
Active Record Inheritance in Rails
Active Record Inheritance in RailsActive Record Inheritance in Rails
Active Record Inheritance in Rails
Sandip Ransing
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
MongoDB
 
Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016
DesertJames
 
Building Dojo in the Cloud
Building Dojo in the CloudBuilding Dojo in the Cloud
Building Dojo in the Cloud
James Thomas
 
Using Dojo
Using DojoUsing Dojo
Using Dojo
Richard Paul
 
Web весна 2013 лекция 6
Web весна 2013 лекция 6Web весна 2013 лекция 6
Web весна 2013 лекция 6
Technopark
 
Novosti u Swift 4 - iOS Talks Osijek
Novosti u Swift 4 - iOS Talks OsijekNovosti u Swift 4 - iOS Talks Osijek
Novosti u Swift 4 - iOS Talks Osijek
Marin Benčević
 
The MEAN stack
The MEAN stack The MEAN stack
The MEAN stack
Nattaya Mairittha
 

What's hot (20)

The Ring programming language version 1.4 book - Part 12 of 30
The Ring programming language version 1.4 book - Part 12 of 30The Ring programming language version 1.4 book - Part 12 of 30
The Ring programming language version 1.4 book - Part 12 of 30
 
Windows ストアーアプリで SQLite を使ってみよう
Windows ストアーアプリで SQLite を使ってみようWindows ストアーアプリで SQLite を使ってみよう
Windows ストアーアプリで SQLite を使ってみよう
 
D3.js and SVG
D3.js and SVGD3.js and SVG
D3.js and SVG
 
The Ring programming language version 1.5.4 book - Part 43 of 185
The Ring programming language version 1.5.4 book - Part 43 of 185The Ring programming language version 1.5.4 book - Part 43 of 185
The Ring programming language version 1.5.4 book - Part 43 of 185
 
How dojo works
How dojo worksHow dojo works
How dojo works
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
 
Design Patterns in Go Code
Design Patterns in Go CodeDesign Patterns in Go Code
Design Patterns in Go Code
 
Coffee script
Coffee scriptCoffee script
Coffee script
 
Intorduction of Playframework
Intorduction of PlayframeworkIntorduction of Playframework
Intorduction of Playframework
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
jQuery Learning
jQuery LearningjQuery Learning
jQuery Learning
 
Extjs + Gears
Extjs + GearsExtjs + Gears
Extjs + Gears
 
Active Record Inheritance in Rails
Active Record Inheritance in RailsActive Record Inheritance in Rails
Active Record Inheritance in Rails
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
 
Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016
 
Building Dojo in the Cloud
Building Dojo in the CloudBuilding Dojo in the Cloud
Building Dojo in the Cloud
 
Using Dojo
Using DojoUsing Dojo
Using Dojo
 
Web весна 2013 лекция 6
Web весна 2013 лекция 6Web весна 2013 лекция 6
Web весна 2013 лекция 6
 
Novosti u Swift 4 - iOS Talks Osijek
Novosti u Swift 4 - iOS Talks OsijekNovosti u Swift 4 - iOS Talks Osijek
Novosti u Swift 4 - iOS Talks Osijek
 
The MEAN stack
The MEAN stack The MEAN stack
The MEAN stack
 

Similar to Writing browser extensions_in_kotlin

Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
Michael Galpin
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
Sergey Bolshchikov
 
Chrome Extensions for Hackers
Chrome Extensions for HackersChrome Extensions for Hackers
Chrome Extensions for Hackers
Cristiano Betta
 
A test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobileA test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobile
GlobalLogic Ukraine
 
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
STX Next
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
Bartosz Kosarzycki
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
erwanl
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
Michael Girouard
 
Dynamic C#
Dynamic C# Dynamic C#
Dynamic C#
Antya Dev
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
IN4308 Lecture 3
IN4308 Lecture 3IN4308 Lecture 3
IN4308 Lecture 3
Eelco Visser
 
JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScript
Laurence Svekis ✔
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentation
Valdis Iljuconoks
 
Mongoid in the real world
Mongoid in the real worldMongoid in the real world
Mongoid in the real world
Kevin Faustino
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
mobl
moblmobl
mobl
zefhemel
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
Anjan Banda
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 

Similar to Writing browser extensions_in_kotlin (20)

Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 
Chrome Extensions for Hackers
Chrome Extensions for HackersChrome Extensions for Hackers
Chrome Extensions for Hackers
 
A test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobileA test framework out of the box - Geb for Web and mobile
A test framework out of the box - Geb for Web and mobile
 
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
Dynamic C#
Dynamic C# Dynamic C#
Dynamic C#
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
IN4308 Lecture 3
IN4308 Lecture 3IN4308 Lecture 3
IN4308 Lecture 3
 
JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScript
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentation
 
Mongoid in the real world
Mongoid in the real worldMongoid in the real world
Mongoid in the real world
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
mobl
moblmobl
mobl
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 

More from xavazque2

258939538 dumping
258939538 dumping258939538 dumping
258939538 dumping
xavazque2
 
380914324 poo-kotlin
380914324 poo-kotlin380914324 poo-kotlin
380914324 poo-kotlin
xavazque2
 
146817358 android
146817358 android146817358 android
146817358 android
xavazque2
 
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlinCurso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
xavazque2
 
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
xavazque2
 
325940441 motion-ui
325940441 motion-ui325940441 motion-ui
325940441 motion-ui
xavazque2
 
371081023 curso-desarrollo-android
371081023 curso-desarrollo-android371081023 curso-desarrollo-android
371081023 curso-desarrollo-android
xavazque2
 
4.1. validaciones-y-excepciones
4.1. validaciones-y-excepciones4.1. validaciones-y-excepciones
4.1. validaciones-y-excepciones
xavazque2
 
3.1 mvc-mvvm-app model-binding
3.1 mvc-mvvm-app model-binding3.1 mvc-mvvm-app model-binding
3.1 mvc-mvvm-app model-binding
xavazque2
 
5.1. stateles stateful-protocolo_http
5.1. stateles stateful-protocolo_http5.1. stateles stateful-protocolo_http
5.1. stateles stateful-protocolo_http
xavazque2
 
435338801 programacion-mobile-android
435338801 programacion-mobile-android435338801 programacion-mobile-android
435338801 programacion-mobile-android
xavazque2
 
457126889 android-pdf
457126889 android-pdf457126889 android-pdf
457126889 android-pdf
xavazque2
 
266521557 apuntes-unidad-formativa-app-inventor
266521557 apuntes-unidad-formativa-app-inventor266521557 apuntes-unidad-formativa-app-inventor
266521557 apuntes-unidad-formativa-app-inventor
xavazque2
 
7. react js-1
7. react js-17. react js-1
7. react js-1
xavazque2
 
Tp1
Tp1Tp1
484719815 pidiendo-ayuda-a-los-angeles-pdf
484719815 pidiendo-ayuda-a-los-angeles-pdf484719815 pidiendo-ayuda-a-los-angeles-pdf
484719815 pidiendo-ayuda-a-los-angeles-pdf
xavazque2
 
484717855 transmutacion-de-energias-pdf
484717855 transmutacion-de-energias-pdf484717855 transmutacion-de-energias-pdf
484717855 transmutacion-de-energias-pdf
xavazque2
 
5.layouts
5.layouts5.layouts
5.layouts
xavazque2
 
6.2. js
6.2. js6.2. js
6.2. js
xavazque2
 
2.1. arena-y-binding
2.1. arena-y-binding2.1. arena-y-binding
2.1. arena-y-binding
xavazque2
 

More from xavazque2 (20)

258939538 dumping
258939538 dumping258939538 dumping
258939538 dumping
 
380914324 poo-kotlin
380914324 poo-kotlin380914324 poo-kotlin
380914324 poo-kotlin
 
146817358 android
146817358 android146817358 android
146817358 android
 
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlinCurso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
Curso profesional-de-desarrollo-de-aplicaciones-android-con-kotlin
 
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
364196144 hogan-pensamiento-no-verbal-comunicacion-y-juego
 
325940441 motion-ui
325940441 motion-ui325940441 motion-ui
325940441 motion-ui
 
371081023 curso-desarrollo-android
371081023 curso-desarrollo-android371081023 curso-desarrollo-android
371081023 curso-desarrollo-android
 
4.1. validaciones-y-excepciones
4.1. validaciones-y-excepciones4.1. validaciones-y-excepciones
4.1. validaciones-y-excepciones
 
3.1 mvc-mvvm-app model-binding
3.1 mvc-mvvm-app model-binding3.1 mvc-mvvm-app model-binding
3.1 mvc-mvvm-app model-binding
 
5.1. stateles stateful-protocolo_http
5.1. stateles stateful-protocolo_http5.1. stateles stateful-protocolo_http
5.1. stateles stateful-protocolo_http
 
435338801 programacion-mobile-android
435338801 programacion-mobile-android435338801 programacion-mobile-android
435338801 programacion-mobile-android
 
457126889 android-pdf
457126889 android-pdf457126889 android-pdf
457126889 android-pdf
 
266521557 apuntes-unidad-formativa-app-inventor
266521557 apuntes-unidad-formativa-app-inventor266521557 apuntes-unidad-formativa-app-inventor
266521557 apuntes-unidad-formativa-app-inventor
 
7. react js-1
7. react js-17. react js-1
7. react js-1
 
Tp1
Tp1Tp1
Tp1
 
484719815 pidiendo-ayuda-a-los-angeles-pdf
484719815 pidiendo-ayuda-a-los-angeles-pdf484719815 pidiendo-ayuda-a-los-angeles-pdf
484719815 pidiendo-ayuda-a-los-angeles-pdf
 
484717855 transmutacion-de-energias-pdf
484717855 transmutacion-de-energias-pdf484717855 transmutacion-de-energias-pdf
484717855 transmutacion-de-energias-pdf
 
5.layouts
5.layouts5.layouts
5.layouts
 
6.2. js
6.2. js6.2. js
6.2. js
 
2.1. arena-y-binding
2.1. arena-y-binding2.1. arena-y-binding
2.1. arena-y-binding
 

Recently uploaded

Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
Pixlogix Infotech
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Zilliz
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 

Recently uploaded (20)

Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 

Writing browser extensions_in_kotlin

  • 1. Writing Browser Extensions in Kotlin Kirill Rakhman (@Cypressious) busradar.com
  • 2. KotlinJS ● No longer expiremental since 1.1.0 ● Can run anywhere where JS runs ○ Websites ○ NodeJS ○ Browser Extensions ● Can call JS ○ the dynamic way ○ the static way ● Benefits from all IDE features you know from Kotlin on the JVM ● Question: Does it make writing browser extensions more pleasant?
  • 3. About dynamic val a: Any = js("{}") a.foo() val b: dynamic = a.asDynamic() b.foo() b["baz"] = "qux"
  • 4. Calling external code external val foo: dynamic external class External { fun callMe() } fun main() { foo.bar() foo.baz.qux = false val e = External() e.callMe() e.somethingElse() }
  • 5. WebExtensions ● A new cross-browser extension API standard ● Implemented by Firefox, Chrome, Opera and Edge to varying degrees ● We’re going to focus on Firefox
  • 6.
  • 7. Calling the WebExtensions API from Kotlin ● external val browser: dynamic ○ easily implemented ○ no compile-time safety ○ no IDE support ● writing external declarations ○ extra effort ○ compile-time safety (assuming you wrote the declarations correctly) ○ IDE support ● code generation from schema ○ no extra effort (because I did it ;) ○ compile-time safety guaranteed by official schema ○ awesome IDE support, including autocompletion, KDoc, deprecation, ...
  • 8. The schema { "name": "sendMessage", "type": "function", "description": "...", "async": "responseCallback", "parameters": [ ..., { "type": "object", "name": "options", "properties": { "frameId": { "type": "integer", "optional": true, "minimum": 0, } }, "optional": true } ] }
  • 10. Transforming JS objects "parameters": [ { "type": "object", "name": "createProperties", "properties": { "windowId": { "type": "integer", "optional": true }, "url": { "type": "string", "optional": true }, "active": { "type": "boolean", "optional": true } } ] class CreateProperties( var windowId: Int? = null, var url: String? = null, var active: Boolean? = null )
  • 11. Transforming JS objects (alternative) "parameters": [ { "type": "object", "name": "createProperties", "properties": { "windowId": { "type": "integer", "optional": true }, "url": { "type": "string", "optional": true }, "active": { "type": "boolean", "optional": true } } ] external interface CreateProperties { var windowId: Int? var url: String? var active: Boolean? } fun CreateProperties( windowId: Int? = null, url: String? = null, active: Boolean? = null ) : CreateProperties { val o: dynamic = js("{}") o.windowId = windowId o.url = url o.active = active return o } https://youtrack.jetbrains.com/issue/KT-21653
  • 12. Transforming Map-like objects "formData": { "type": "object", "properties": {}, "additionalProperties": { "type": "array", "items": { "type": "string" } } } { "type": "object", "patternProperties": { "^[1-9]d*$": {"$ref": "ImageDataType"} } } class FormData { inline operator fun get(key: String): Array<String> = asDynamic()[key] inline operator fun set(key: String, value: Array<String>) { asDynamic()[key] = value } }
  • 13. Transforming union types in function parameters "functions": [ { "name": "get", "type": "function", "async": "callback", "parameters": [ { "name": "idOrIdList", "choices": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ] } ... external class BookmarksNamespace { fun get(idOrIdList: String): Promise<Array<BookmarkTreeNode>> fun get(idOrIdList: Array<String>): Promise<Array<BookmarkTreeNode>> }
  • 14. Transforming union types { "id": "OnClickData", "type": "object", "properties": { "menuItemId": { "choices": [ { "type": "integer" }, { "type": "string" } ] }, ... class OnClickData( var menuItemId: MenuItemId ) typealias MenuItemId = Any :(
  • 15. Transforming Events "events": [ { "name": "onCreated", "type": "function", "parameters": [ { "$ref": "Tab", "name": "tab" } ] }, ... external class Event<in T> { fun addListener(listener: T) fun removeListener(listener: T) fun hasListener(listener: T): Boolean } val onCreated: Event<(tab: Tab) -> Unit>
  • 16. Generating Code ● KotlinPoet is “a Kotlin and Java API for generating .kt source files.” ● Heavy use of the Builder pattern ● Make use of information like optional parameters, deprecation, KDoc, ... private fun generateFunction(f: Function, parameters: List<Parameter>): FunSpec { val builder = FunSpec.builder(f. name) f.description?.let { builder.addKdoc( it + "n") } parameters.forEach { builder.addParameter(generateParameter( it.name!!, it).build()) } f.deprecated?.let { builder.addAnnotation(AnnotationSpec.builder( Deprecated::class).addMember(""$it"").build()) } returnType(f)?. let { builder.returns( it) } return builder.build() }
  • 17. The generated code external val browser: Browser external class Browser { val tabs: TabsNamespace ... } external class TabsNamespace { /** ... */ fun move(tabIds: Int, moveProperties: MoveProperties): Promise<Tabs2> /** ... */ fun move(tabIds: Array<Int>, moveProperties: MoveProperties): Promise<Tabs2> ... } class MoveProperties(...) https://github.com/cypressious/kotlin-webextensions-declarations
  • 19. Future improvements ● Tooling ○ Multiple projects for different output files are annoying ● Keeping up with API updates ○ Auto generate using Gradle plugin? ● Use external interfaces instead of classes ○ Smaller compiled JS ● Make it compatible with Chrome ○ Is not Promise based ○ Base object ○ Polyfill¹ already exist ¹ https://github.com/mozilla/webextension-polyfill
  • 20. Thank you for your attention Kirill Rakhman cypressious rakhman.info
  • 21. Writing the plugin buildscript { ext.kotlin_version = '1.2.70' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } version '0.1' https://github.com/cypressious/webextension-search-kotlin-docs allprojects { apply plugin: 'kotlin2js' apply plugin: 'kotlin-dce-js' repositories { mavenCentral() maven { url 'https://jitpack.io' } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" compile 'com.github.cypressious.kotlin-webextensions-declarations:w ebextensions-declarations:v0.1' } compileKotlin2Js { kotlinOptions.sourceMap = true kotlinOptions.sourceMapEmbedSources = "always" } }
  • 22. Writing the plugin { "description": "Adds a context menu item to search for the selected word in the Kotlin documentation", "manifest_version": 2, "name": "Search Kotlin", "version": "1.0", "icons": { }, "background": { "scripts": [ "build/kotlin-js-min/main/kotlin.js", "build/kotlin-js-min/main/declarations.js", "build/kotlin-js-min/main/ff-search-kotlin.js" ] }, "permissions": [ "menus" ] } https://github.com/cypressious/webextension-search-kotlin-docs
  • 23. Writing the plugin import menus.CreateProperties import webextensions. browser fun main(args: Array<String>) { browser.menus.create(CreateProperties( id = "search-kotlin", title = "Search in Kotlin Docs", contexts = arrayOf("selection") )) browser.menus.onClicked.addListener { info, tab -> when (info.menuItemId) { "search-kotlin" -> { browser.tabs.create(tabs.CreateProperties( url = "http://kotlinlang.org/?q=${info.selectionText}&p=0" )) } } } } https://github.com/cypressious/webextension-search-kotlin-docs