-
Notifications
You must be signed in to change notification settings - Fork 263
Bug 837494 - re-implement contentStyle*
using the new nsIDOMWindowUtils methods
#839
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | ||
- License, v. 2.0. If a copy of the MPL was not distributed with this | ||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | ||
|
||
The `mod` module provides functions to modify a page content. | ||
|
||
<api name="attachTo"> | ||
@function | ||
Function applies given `modification` to a given `window`. | ||
|
||
For example, the following code applies a style to a content window, adding | ||
a border to all divs in page: | ||
|
||
var attachTo = require("sdk/content/mod").attachTo; | ||
var Style = require("sdk/stylesheet/style").Style; | ||
|
||
var style = Style({ | ||
source: "div { border: 4px solid gray }" | ||
}); | ||
|
||
// assuming window points to the content page we want to modify | ||
attachTo(style, window); | ||
|
||
@param modification {object} | ||
The modification we want to apply to the target. | ||
|
||
@param window {nsIDOMWindow} | ||
The window to be modified. | ||
</api> | ||
|
||
<api name="detachFrom"> | ||
@function | ||
Function removes attached `modification` from a given `window`. | ||
If `window` is not specified, `modification` is removed from all the windows | ||
it's being attached to. | ||
|
||
For example, the following code applies and removes a style to a content | ||
window, adding a border to all divs in page: | ||
|
||
var { attachTo, detachFrom } = require("sdk/content/mod"); | ||
var Style = require("sdk/stylesheet/style").Style; | ||
|
||
var style = Style({ | ||
source: "div { border: 4px solid gray }" | ||
}); | ||
|
||
// assuming window points to the content page we want to modify | ||
attachTo(style, window); | ||
// ... | ||
detachFrom(style, window); | ||
|
||
@param modification {object} | ||
The modification we want to remove from the target | ||
|
||
@param window {nsIDOMWindow} | ||
The window to be modified. | ||
If `window` is not provided `modification` is removed from all targets it's | ||
being attached to. | ||
</api> | ||
|
||
<api name="getTargetWindow"> | ||
@function | ||
Function takes `target`, value representing content (page) and returns | ||
`nsIDOMWindow` for that content. | ||
If `target` does not represents valid content `null` is returned. | ||
For example target can be a content window itself in which case it's will be | ||
returned back. | ||
|
||
@param target {object} | ||
The object for which we want to obtain the window represented or contained. | ||
If a `nsIDOMWindow` is given, it works as an identify function, returns | ||
`target` itself. | ||
@returns {nsIDOMWindow|null} | ||
The window represented or contained by the `target`, if any. Returns `null` | ||
otherwise. | ||
</api> | ||
|
||
<api name="attach"> | ||
@function | ||
Function applies given `modification` to a given `target` representing a | ||
content to be modified. | ||
|
||
@param modification {object} | ||
The modification we want to apply to the target | ||
|
||
@param target {object} | ||
Target is a value that representing content to be modified. It is valid only | ||
when `getTargetWindow(target)` returns nsIDOMWindow of content it represents. | ||
</api> | ||
|
||
<api name="detach"> | ||
@function | ||
Function removes attached `modification`. If `target` is specified | ||
`modification` is removed from that `target` only, otherwise `modification` is | ||
removed from all the targets it's being attached to. | ||
|
||
@param modification {object} | ||
The modification we want to remove from the target | ||
|
||
@param target {object} | ||
Target is a value that representing content to be modified. It is valid only | ||
when `getTargetWindow(target)` returns `nsIDOMWindow` of content it represents. | ||
If `target` is not provided `modification` is removed from all targets it's | ||
being attached to. | ||
</api> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | ||
- License, v. 2.0. If a copy of the MPL was not distributed with this | ||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | ||
|
||
Module provides `Style` function that can be used to construct content style | ||
modification via stylesheet files or CSS rules. | ||
|
||
<api name="Style"> | ||
@class | ||
<api name="Style"> | ||
@constructor | ||
The Style constructor creates an object that represents style modifications | ||
via stylesheet file(s) or/and CSS rules. Stylesheet file URL(s) are verified | ||
to be local to an add-on, while CSS rules are virified to be a string or | ||
array of strings. | ||
|
||
The style created can be applied to a content by calling `attach`, | ||
and removed using `detach`. Those functions are part of [content/mod](modules/sdk/content/mod.html) module. | ||
@param options {object} | ||
Options for the style. All these options are optional. Although if you | ||
don't supply any stylesheet or CSS rules, your style won't be very useful. | ||
|
||
@prop uri {string,array} | ||
A string, or an array of strings, that represents local URI to stylesheet. | ||
@prop source {string,array} | ||
A string, or an array of strings, that contains CSS rules. Those rules | ||
are applied after the rules in the stylesheet specified with `uri` options, | ||
if provided. | ||
@prop [type="author"] {string} | ||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | ||
and `"author"`. | ||
If not provided, the default value is `"author"`. | ||
</api> | ||
|
||
<api name="source"> | ||
@property {string} | ||
An array of strings that contains the CSS rule(s) specified in the constructor's | ||
option; `null` if no `source` option was given to the constructor. | ||
This property is read-only. | ||
</api> | ||
<api name="uri"> | ||
@property {string} | ||
An array of strings that contains the stylesheet local URI(s) specified in the | ||
constructor's option; `null` if no `uri` option was given to the | ||
constructor. | ||
This property is read-only. | ||
</api> | ||
<api name="type"> | ||
@property {string} | ||
The type of the sheet. If no type is provided in constructor's option, | ||
it returns the default value, `"author"`. This property is read-only. | ||
</api> | ||
</api> | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!-- This Source Code Form is subject to the terms of the Mozilla Public | ||
- License, v. 2.0. If a copy of the MPL was not distributed with this | ||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> | ||
|
||
Module provides helper functions for working with stylesheets. | ||
|
||
<api name="loadSheet"> | ||
@function | ||
Synchronously loads a style sheet from `uri` and adds it to the list of | ||
additional style sheets of the document. | ||
The sheets added takes effect immediately, and only on the document of the | ||
`window` given. | ||
@param window {nsIDOMWindow} | ||
@param uri {string, nsIURI} | ||
@param [type="author"] {string} | ||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | ||
and `"author"`. | ||
If not provided, the default value is `"author"`. | ||
</api> | ||
|
||
<api name="removeSheet"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember if it was me who suggested it in first place but I think it's better to have load/unload or add/remove Sheet There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was made to be consistent with the platform's name. I think they're actually good and they express exactly what they did. Why you think is no good with them? |
||
@function | ||
Remove the document style sheet at `sheetURI` from the list of additional | ||
style sheets of the document. The removal takes effect immediately. | ||
@param window {nsIDOMWindow} | ||
@param uri {string, nsIURI} | ||
@param [type="author"] {string} | ||
The type of the sheet. It accepts the following values: `"agent"`, `"user"` | ||
and `"author"`. | ||
If not provided, the default value is `"author"`. | ||
</api> | ||
|
||
<api name="isTypeValid"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked with native language speaker (aka, @jsantell) about if noun should be before or after the the "valid" part, and he said that About the too generic name: we have tons of generic name, but I always though that the module worked as context (see for instance |
||
@function | ||
Verifies that the `type` given is a valid stylesheet's type. | ||
The values considered valid are: `"agent"`, `"user"` and `"author"`. | ||
@param type {string} | ||
The type of the sheet. | ||
@returns {boolean} | ||
`true` if the `type` given is valid, otherwise `false`. | ||
</api> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||
/* vim:set ts=2 sw=2 sts=2 et: */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
"use strict"; | ||
|
||
module.metadata = { | ||
"stability": "experimental" | ||
}; | ||
|
||
const { Ci } = require("chrome"); | ||
const method = require("method/core"); | ||
const { add, remove, iterator } = require("../lang/weak-set"); | ||
|
||
let getTargetWindow = method("getTargetWindow"); | ||
|
||
getTargetWindow.define(function (target) { | ||
if (target instanceof Ci.nsIDOMWindow) | ||
return target; | ||
if (target instanceof Ci.nsIDOMDocument) | ||
return target.defaultView || null; | ||
|
||
return null; | ||
}); | ||
|
||
exports.getTargetWindow = getTargetWindow; | ||
|
||
let attachTo = method("attachTo"); | ||
exports.attachTo = attachTo; | ||
|
||
let detachFrom = method("detatchFrom"); | ||
exports.detachFrom = detachFrom; | ||
|
||
function attach(modification, target) { | ||
let window = getTargetWindow(target); | ||
|
||
attachTo(modification, window); | ||
|
||
// modification are stored per content; `window` reference can still be the | ||
// same even if the content is changed, therefore `document` is used instead. | ||
add(modification, window.document); | ||
} | ||
exports.attach = attach; | ||
|
||
function detach(modification, target) { | ||
if (target) { | ||
let window = getTargetWindow(target); | ||
detachFrom(modification, window); | ||
remove(modification, window.document); | ||
} | ||
else { | ||
let documents = iterator(modification); | ||
for (let document of documents) { | ||
detachFrom(modification, document.defaultView); | ||
remove(modification, document); | ||
} | ||
} | ||
} | ||
exports.detach = detach; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
"use strict"; | ||
|
||
const { Cu } = require("chrome"); | ||
|
||
function makeGetterFor(Type) { | ||
let cache = new WeakMap(); | ||
|
||
return function getFor(target) { | ||
if (!cache.has(target)) | ||
cache.set(target, new Type()); | ||
|
||
return cache.get(target); | ||
} | ||
} | ||
|
||
let getLookupFor = makeGetterFor(WeakMap); | ||
let getRefsFor = makeGetterFor(Set); | ||
|
||
function add(target, value) { | ||
if (has(target, value)) | ||
return; | ||
|
||
getLookupFor(target).set(value, true); | ||
getRefsFor(target).add(Cu.getWeakReference(value)); | ||
} | ||
exports.add = add; | ||
|
||
function remove(target, value) { | ||
getLookupFor(target).delete(value); | ||
} | ||
exports.remove = remove; | ||
|
||
function has(target, value) { | ||
return getLookupFor(target).has(value); | ||
} | ||
exports.has = has; | ||
|
||
function clear(target) { | ||
getLookupFor(target).clear(); | ||
getRefsFor(target).clear(); | ||
} | ||
exports.clear = clear; | ||
|
||
function iterator(target) { | ||
let refs = getRefsFor(target); | ||
|
||
for (let ref of refs) { | ||
let value = ref.get(); | ||
|
||
if (has(target, value)) | ||
yield value; | ||
else | ||
refs.delete(ref); | ||
} | ||
} | ||
exports.iterator = iterator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also mention in docs that style can be applied to a content by calling
attach(style, window)
or removed usingdetach(style, window)
and would refer tocontent/mod
docs for more details.